From 80e691699f2b236e4af80f8c1178cde07b458da3 Mon Sep 17 00:00:00 2001 From: mogguh Date: Wed, 11 Apr 2007 14:10:41 +0000 Subject: Feature: ScoreScreen now has the ability to show extra texts (UThemes.pas, UScreenScore.pas) Feature: Hit golden note effect, is now even more astonishing (UGraphicClasses.pas) Feature: It's now possible to turn of GoldenNoteTwinkle (UDraw.pas) BugFix: OptionsAdvanced is now opened correctly, instead of producing a bug (UGraphic.pas) BugFix: Modified some language entries to fit option screen (optionen instead of einstellungen) (German.ini) git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@78 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UDraw.pas | 2 + Game/Code/Classes/UGraphic.pas | 2 +- Game/Code/Classes/UGraphicClasses.pas | 362 +++++++++++++++++++++------------- Game/Code/Classes/UThemes.pas | 5 + 4 files changed, 233 insertions(+), 138 deletions(-) (limited to 'Game/Code/Classes') diff --git a/Game/Code/Classes/UDraw.pas b/Game/Code/Classes/UDraw.pas index 952bad07..e2c01b4b 100644 --- a/Game/Code/Classes/UDraw.pas +++ b/Game/Code/Classes/UDraw.pas @@ -430,6 +430,8 @@ var // passing on NrGracza... hope this is really something like the player-number, not only // some kind of weird index into a colour-table + + if (Ini.EffectGolden=1) then GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, NrGracza); end; // if end; diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas index 9f3e6667..c3ce0f00 100644 --- a/Game/Code/Classes/UGraphic.pas +++ b/Game/Code/Classes/UGraphic.pas @@ -404,7 +404,7 @@ begin Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Themes', 3); Log.BenchmarkStart(3); ScreenOptionsRecord := TScreenOptionsRecord.Create; Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Record', 3); Log.BenchmarkStart(3); - ScreenOptionsAdvanced := TScreenOptionsAdvanced.Create; + ScreenOptionsAdvanced := TScreenOptionsAdvanced.Create(''); Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Advanced', 3); Log.BenchmarkStart(3); ScreenEditSub := TScreenEditSub.Create(''); Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Sub', 3); Log.BenchmarkStart(3); diff --git a/Game/Code/Classes/UGraphicClasses.pas b/Game/Code/Classes/UGraphicClasses.pas index 34a964b2..5fa22575 100644 --- a/Game/Code/Classes/UGraphicClasses.pas +++ b/Game/Code/Classes/UGraphicClasses.pas @@ -1,18 +1,30 @@ unit UGraphicClasses; interface - +const DelayBetweenFrames : Cardinal = 100; type + + TParticleType=(GoldenNote, PerfectNote, NoteHitTwinkle, PerfectLineTwinkle); + + TColour3f = Record + r, g, b: Real; + end; + TParticle = Class X, Y : Real; //Position + W, H : Cardinal; //dimensions of particle + Col : TColour3f; // Colour of particle Frame : Byte; //act. Frame Tex : Cardinal; //Tex num from Textur Manager Live : Byte; //How many Cycles before Kill - RecIndex : Integer; //To which rectangle this particle belongs - StarType : Integer; // 1: GoldenNote | 2: PerfectNote + RecIndex : Integer; //To which rectangle this particle belongs (only GoldenNote) + StarType : TParticleType; // GoldenNote | PerfectNote | NoteHitTwinkle | PerfectLineTwinkle + Alpha : Real; // used for fading... + mX, mY : Real; // movement-vector for PerfectLineTwinkle - Constructor Create(cX,cY: Real; cTex: Cardinal; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : Integer); + Constructor Create(cX,cY: Real; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal); procedure Draw; + procedure LiveOn; end; RectanglePositions = Record @@ -29,13 +41,19 @@ type Particle : array of TParticle; LastTime : Cardinal; RecArray : Array of RectanglePositions; - TwinkleArray : Array[0..5] of PerfectNotePositions; // store position of last twinkle for every player + TwinkleArray : Array[0..5] of Real; // store x-position of last twinkle for every player PerfNoteArray : Array of PerfectNotePositions; - KillallTime : Cardinal; // Timestamp set when Killall is called constructor Create; + destructor Destroy; override; procedure Draw; - function Spawn(X, Y: Real; Tex: Cardinal; Live: Byte; StartFrame : Integer; RecArrayIndex : Integer; StarType : Integer): Cardinal; + function Spawn(X, Y: Real; + Live: Byte; + StartFrame: Integer; + RecArrayIndex: Integer; // this is only used with GoldenNotes + StarType: TParticleType; + Player: Cardinal // for PerfectLineTwinkle + ): Cardinal; procedure SpawnRec(); procedure Kill(index: Cardinal); procedure KillAll(); @@ -49,53 +67,109 @@ var GoldenRec : TEffectManager; implementation uses sysutils, Windows,OpenGl12, UThemes, USkins, UGraphic, UDrawTexture, UTexture, math, dialogs; -const - KillallDelay: Integer = 100; - - //TParticle -Constructor TParticle.Create(cX,cY: Real; cTex: Cardinal; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : Integer); +Constructor TParticle.Create(cX,cY: Real; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal); begin + inherited Create; X := cX; Y := cY; - Tex := cTex; Live := cLive; Frame:= cFrame; RecIndex := cRecArrayIndex; StarType := cStarType; -end; - - -procedure TParticle.Draw; -var - W, H: real; - Alpha : real; -begin - //Fade Eyecandy - - Case StarType of - 1: + Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out + case cStarType of + GoldenNote: begin - Alpha := (-cos((Frame+1)*2*pi/16)+1); + Tex := Tex_Note_Star.TexNum; W := 20; H := 20; - glColor4f(0.99, 1, 0.6, Alpha); + Col.r := 0.99; + Col.g := 1; + Col.b := 0.6; end; - 2: + PerfectNote: begin - Alpha := (-cos((Frame+1)*2*pi/16)+1); + Tex := Tex_Note_Perfect_Star.TexNum; W := 30; H := 30; - glColor4f(1, 1, 0.95, Alpha); + Col.r := 1; + Col.g := 1; + Col.b := 0.95; end; - 3: + NoteHitTwinkle: begin - Alpha := (Live/3); + Tex := Tex_Note_Star.TexNum; + Alpha := (Live/10); // linear fade-out W := 15; H := 15; - glColor4f(1, 1, 0.9, Alpha); + Col.r := 1; + Col.g := 1; + Col.b := RandomRange(10*Live,100)/80; //0.9; + end; + PerfectLineTwinkle: + begin + Tex := Tex_Note_Star.TexNum; + W := RandomRange(10,30); + H := W; + // hier muss entsprechend des players farbe gesetzt werden (sollten wir dann auch übergeben bekommen) + // case Player of + // ... + Col.r := 1; + Col.g := 0.5; + Col.b := 0.5; + mX := RandomRange(-5,5); + mY := RandomRange(-5,5); + end; + else // just some random default values + begin + Tex := Tex_Note_Star.TexNum; + Alpha := 1; + W := 20; + H := 20; + Col.r := 1; + Col.g := 1; + Col.b := 1; end; end; +end; + +procedure TParticle.LiveOn; +begin + //Live = 0 => Live forever ?? die werden doch aber im Manager bei Draw getötet, wenns 0 is + if (Live > 0) then + Dec(Live); + + // animate frames + Frame := ( Frame + 1 ) mod 16; + + // make our particles do funny stuff (besides being animated) + case StarType of + GoldenNote: + begin + Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out + end; + PerfectNote: + begin + Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out + end; + NoteHitTwinkle: + begin + Alpha := (Live/10); // linear fade-out + end; + PerfectLineTwinkle: + begin + Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out + // move around + X := X + mX; + Y := Y + mY; + end; + end; +end; + +procedure TParticle.Draw; +begin + glColor4f(Col.r, Col.g, Col.b, Alpha); glBindTexture(GL_TEXTURE_2D, Tex); glEnable(GL_TEXTURE_2D); @@ -112,44 +186,43 @@ begin end; glcolor4f(1,1,1,1); end; +// end of TParticle - +// TEffectManager constructor TEffectManager.Create; var c: Cardinal; begin + inherited; LastTime := GetTickCount; - KillallTime := LastTime; for c:=0 to 5 do begin - TwinkleArray[c].xPos := 0; - TwinkleArray[c].yPos := 0; + TwinkleArray[c] := 0; end; end; +destructor TEffectManager.Destroy; +begin + Killall; + inherited; +end; + procedure TEffectManager.Draw; var I: Integer; CurrentTime: Cardinal; -const - DelayBetweenFrames : Integer = 100; +//const +// DelayBetweenFrames : Cardinal = 100; begin CurrentTime := GetTickCount; //Manage particle life - if (CurrentTime > (LastTime + DelayBetweenFrames)) then + if (CurrentTime - LastTime) > DelayBetweenFrames then begin LastTime := CurrentTime; - for I := 0 to high(Particle) do - begin - Particle[I].Frame := (Particle[I].Frame + 1 ) mod 16; - //Live = 0 => Live forever - if (Particle[I].Live > 0) then - begin - Dec(Particle[I].Live); - end; - end; + for I := 0 to high(Particle) do + Particle[I].LiveOn; end; I := 0; @@ -173,15 +246,15 @@ begin end; end; - -function TEffectManager.Spawn(X, Y: Real; Tex: Cardinal; Live: Byte; StartFrame : Integer; RecArrayIndex : Integer; StarType : Integer): Cardinal; +// this method creates just one particle +function TEffectManager.Spawn(X, Y: Real; Live: Byte; StartFrame : Integer; RecArrayIndex : Integer; StarType : TParticleType; Player: Cardinal): Cardinal; begin Result := Length(Particle); SetLength(Particle, (Result + 1)); - Particle[Result] := TParticle.Create(X, Y, Tex, Live, StartFrame, RecArrayIndex, StarType); + Particle[Result] := TParticle.Create(X, Y, Live, StartFrame, RecArrayIndex, StarType, Player); end; - +// manage Sparkling of GoldenNote Bars procedure TEffectManager.SpawnRec(); Var Xkatze, Ykatze : Real; @@ -197,46 +270,46 @@ for P:= 0 to high(RecArray) do Xkatze := RandomRange(Ceil(RecArray[P].xTop), Ceil(RecArray[P].xBottom)); Ykatze := RandomRange(Ceil(RecArray[P].yTop), Ceil(RecArray[P].yBottom)); RandomFrame := RandomRange(0,14); - Spawn(Xkatze, Ykatze, Tex_Note_Star.TexNum, 16 - RandomFrame, RandomFrame, P, 1); + // Spawn a GoldenNote Particle + Spawn(Xkatze, Ykatze, 16 - RandomFrame, RandomFrame, P, GoldenNote, 0); inc(RecArray[P].CurrentStarCount); end; end; draw; end; - +// kill one particle (with given index in our particle array) procedure TEffectManager.Kill(Index: Cardinal); var - LastParticleIndex : Cardinal; + LastParticleIndex : Integer; begin -// We put the last element of the array on the place where our element_to_delete resides and then we shorten the array - cool, hu? :P - -LastParticleIndex := high(Particle); -if not(LastParticleIndex = -1) then +// delete particle indexed by Index, +// overwrite it's place in our particle-array with the particle stored at the last array index, +// shorten array + LastParticleIndex := high(Particle); + if not(LastParticleIndex = -1) then // is there still a particle to delete? begin - Try - Finally - if not(Particle[Index].RecIndex = -1) then - dec(RecArray[Particle[Index].RecIndex].CurrentStarCount); - Particle[Index].Destroy; - Particle[Index] := Particle[LastParticleIndex]; - SetLength(Particle, LastParticleIndex); - end; - end; + if not(Particle[Index].RecIndex = -1) then // if it is a GoldenNote particle... + dec(RecArray[Particle[Index].RecIndex].CurrentStarCount); // take care of its associated GoldenRec + // now get rid of that particle + Particle[Index].Destroy; + Particle[Index] := Particle[LastParticleIndex]; + SetLength(Particle, LastParticleIndex); + end; end; +// clean up all particles and management structures procedure TEffectManager.KillAll(); var c: Cardinal; begin //It's the kill all kennies rotuine - while Length(Particle) > 0 do + while Length(Particle) > 0 do // kill all existing particles Kill(0); - SetLength(RecArray,0); - SetLength(PerfNoteArray,0); + SetLength(RecArray,0); // remove GoldenRec positions + SetLength(PerfNoteArray,0); // remove PerfectNote positions for c:=0 to 5 do begin - TwinkleArray[c].xPos:=0; - TwinkleArray[c].yPos:=0; + TwinkleArray[c] := 0; // reset GoldenNoteHit memory end; end; @@ -244,95 +317,110 @@ procedure TeffectManager.GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integ //Twinkle stars while golden note hit // this is called from UDraw.pas, SingDrawPlayerCzesc var - C, P, XKatze, YKatze: Integer; - CurrentTime: Cardinal; + C, P, XKatze, YKatze, LKatze: Integer; + H: Real; begin - CurrentTime := GetTickCount; - //delay after Killall - if (CurrentTime > (KillallTime + KillallDelay)) then - // make sure we spawn only one time at one position - if (TwinkleArray[Player].xPos < Right) then - For P := 0 to high(RecArray) do // Are we inside a GoldenNoteRectangle? + // make sure we spawn only one time at one position + if (TwinkleArray[Player] < Right) then + For P := 0 to high(RecArray) do // Are we inside a GoldenNoteRectangle? + begin + H := (Top+Bottom)/2; // helper... + with RecArray[P] do + if ((xBottom >= Right) and (xTop <= Right) and + (yTop <= H) and (yBottom >= H)) then begin - if ((RecArray[P].xBottom >= Right) and - (RecArray[P].xTop <= Right) and - (RecArray[P].yTop <= (Top+Bottom)/2) and - (RecArray[P].yBottom >= (Top+Bottom)/2)) then + TwinkleArray[Player] := Right; // remember twinkle position for this player + for C := 1 to 20 do begin - TwinkleArray[Player].xPos:=Right; - - for C := 1 to 8 do - begin - Ykatze := RandomRange(ceil(Top) , ceil(Bottom)); - XKatze := RandomRange(-7,3); - Spawn(Ceil(Right)+XKatze, YKatze, Tex_Note_Star.TexNum, 3, 0, -1, 3); - end; - exit; // found a GoldenRec, did spawning stuff... done + Ykatze := RandomRange(ceil(Top) , ceil(Bottom)); + XKatze := RandomRange(-7,3); + LKatze := RandomRange(4,10); + Spawn(Ceil(Right)+XKatze, YKatze, LKatze, 0, -1, NoteHitTwinkle, 0); end; + for C := 1 to 5 do + begin + Ykatze := RandomRange(ceil(Top)-6 , ceil(Top)); + XKatze := RandomRange(-5,1); + LKatze := RandomRange(2,3); + Spawn(Ceil(Right)+XKatze, YKatze, LKatze, 0, -1, NoteHitTwinkle, 0); + end; + for C := 1 to 5 do + begin + Ykatze := RandomRange(ceil(Bottom), ceil(Bottom)+6); + XKatze := RandomRange(-5,1); + LKatze := RandomRange(2,3); + Spawn(Ceil(Right)+XKatze, YKatze, LKatze, 0, -1, NoteHitTwinkle, 0); + end; + for C := 1 to 3 do + begin + Ykatze := RandomRange(ceil(Top)-10 , ceil(Top)-6); + XKatze := RandomRange(-5,1); + LKatze := RandomRange(1,2); + Spawn(Ceil(Right)+XKatze, YKatze, LKatze, 0, -1, NoteHitTwinkle, 0); + end; + for C := 1 to 3 do + begin + Ykatze := RandomRange(ceil(Bottom)+6 , ceil(Bottom)+10); + XKatze := RandomRange(-5,1); + LKatze := RandomRange(1,2); + Spawn(Ceil(Right)+XKatze, YKatze, LKatze, 0, -1, NoteHitTwinkle, 0); + end; + + exit; // found a matching GoldenRec, did spawning stuff... done end; + end; end; procedure TEffectManager.SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real); var P : Integer; // P like used in Positions NewIndex : Integer; - CurrentTime: Cardinal; begin - CurrentTime := GetTickCount; - //delay after Killall - if (CurrentTime > (KillallTime + KillallDelay)) then - begin - For P := 0 to high(RecArray) do // Do we already have that "new" position? - begin - if ((ceil(RecArray[P].xTop) = ceil(Xtop)) and (ceil(RecArray[P].yTop) = ceil(Ytop))) then - exit; // it's already in the array, so we don't have to create a new one - end; + For P := 0 to high(RecArray) do // Do we already have that "new" position? + begin + if ((ceil(RecArray[P].xTop) = ceil(Xtop)) and (ceil(RecArray[P].yTop) = ceil(Ytop))) then + exit; // it's already in the array, so we don't have to create a new one + end; // we got a new position, add the new positions to our array - NewIndex := Length(RecArray); - SetLength(RecArray, NewIndex + 1); - RecArray[NewIndex].xTop := Xtop; - RecArray[NewIndex].yTop := Ytop; - RecArray[NewIndex].xBottom := Xbottom; - RecArray[NewIndex].yBottom := Ybottom; - RecArray[NewIndex].TotalStarCount := ceil(Xbottom - Xtop) div 12 + 3; - RecArray[NewIndex].CurrentStarCount := 0; - end; + NewIndex := Length(RecArray); + SetLength(RecArray, NewIndex + 1); + RecArray[NewIndex].xTop := Xtop; + RecArray[NewIndex].yTop := Ytop; + RecArray[NewIndex].xBottom := Xbottom; + RecArray[NewIndex].yBottom := Ybottom; + RecArray[NewIndex].TotalStarCount := ceil(Xbottom - Xtop) div 12 + 3; + RecArray[NewIndex].CurrentStarCount := 0; end; procedure TEffectManager.SavePerfectNotePos(Xtop, Ytop: Real); var P : Integer; // P like used in Positions NewIndex : Integer; - RandomFrame : Integer; Xkatze, Ykatze : Integer; - CurrentTime: Cardinal; begin - CurrentTime := GetTickCount; - //delay after Killall - if (CurrentTime > (KillallTime + KillallDelay)) then - begin - For P := 0 to high(PerfNoteArray) do // Do we already have that "new" position? - begin - if ((ceil(PerfNoteArray[P].xPos) = ceil(Xtop)) and (ceil(PerfNoteArray[P].yPos) = ceil(Ytop))) then - exit; // it's already in the array, so we don't have to create a new one - end; + For P := 0 to high(PerfNoteArray) do // Do we already have that "new" position? + begin + with PerfNoteArray[P] do + if ((ceil(xPos) = ceil(Xtop)) and (ceil(yPos) = ceil(Ytop))) then + exit; // it's already in the array, so we don't have to create a new one + end; //for // we got a new position, add the new positions to our array - NewIndex := Length(PerfNoteArray); - SetLength(PerfNoteArray, NewIndex + 1); - PerfNoteArray[NewIndex].xPos := Xtop; - PerfNoteArray[NewIndex].yPos := Ytop; + NewIndex := Length(PerfNoteArray); + SetLength(PerfNoteArray, NewIndex + 1); + PerfNoteArray[NewIndex].xPos := Xtop; + PerfNoteArray[NewIndex].yPos := Ytop; - for P:= 0 to 2 do - begin - Xkatze := RandomRange(ceil(Xtop) - 5 , ceil(Xtop) + 10); - Ykatze := RandomRange(ceil(Ytop) - 5 , ceil(Ytop) + 10); - RandomFrame := RandomRange(0,14); - Spawn(Xkatze, Ykatze, Tex_Note_Perfect_Star.TexNum, 16 - RandomFrame, RandomFrame, -1, 2); - end; - end; + for P:= 0 to 2 do + begin + Xkatze := RandomRange(ceil(Xtop) - 5 , ceil(Xtop) + 10); + Ykatze := RandomRange(ceil(Ytop) - 5 , ceil(Ytop) + 10); + RandomFrame := RandomRange(0,14); + Spawn(Xkatze, Ykatze, 16 - RandomFrame, RandomFrame, -1, PerfectNote, 0); + end; //for end; + end. diff --git a/Game/Code/Classes/UThemes.pas b/Game/Code/Classes/UThemes.pas index 17983a60..d7adb61a 100644 --- a/Game/Code/Classes/UThemes.pas +++ b/Game/Code/Classes/UThemes.pas @@ -290,7 +290,10 @@ type TextArtist: TThemeText; TextTitle: TThemeText; + TextArtistTitle: TThemeText; + PlayerStatic: array[1..6] of AThemeStatic; + PlayerTexts: array[1..6] of AThemeText; TextName: array[1..6] of TThemeText; TextScore: array[1..6] of TThemeText; @@ -917,9 +920,11 @@ begin ThemeLoadText(Score.TextArtist, 'ScoreTextArtist'); ThemeLoadText(Score.TextTitle, 'ScoreTextTitle'); + ThemeLoadText(Score.TextArtistTitle, 'ScoreTextArtistTitle'); for I := 1 to 6 do begin ThemeLoadStatics(Score.PlayerStatic[I], 'ScorePlayer' + IntToStr(I) + 'Static'); + ThemeLoadTexts(Score.PlayerTexts[I], 'ScorePlayer' + IntToStr(I) + 'Text'); ThemeLoadText(Score.TextName[I], 'ScoreTextName' + IntToStr(I)); ThemeLoadText(Score.TextScore[I], 'ScoreTextScore' + IntToStr(I)); -- cgit v1.2.3