There is also this tutorial which uses the object corners and tile indices too
http://www.metanetsoftware.com/technique/tutorialB.html
cheers,
Paul
There is also this tutorial which uses the object corners and tile indices too
http://www.metanetsoftware.com/technique/tutorialB.html
cheers,
Paul
Games:
Seafox
Pages:
Syntax Error Software
itch.io page
Online Chess
http://gameknot.com/#paul_nicholls
Hello
I'm manipulating the vx and vy on TForm1.OnIDLE like this :
The DoMOVE procedure for the Character object...Code:ActTime := ActTime + AdPerCounter.TimeGap; if ActTime > 100 then begin Blurp.vx:=0; Blurp.vy:=0; if GetKeyState(VK_LEFT) < 0 then begin Blurp.vx:=-16; end; if GetKeyState(VK_RIGHT) < 0 then begin Blurp.vx:=+16; end; if GetKeyState(VK_UP) < 0 then begin Blurp.vy:=-16 end; if GetKeyState(VK_DOWN) < 0 then begin Blurp.vy:=16 end; ActTime := 0; end;
I've also modified the code for getCorners, for some reason I did not notice HALF heihgt and HALF width, since my character is 32x32, I'm using 16 here. This part now should be ok, thanks to your ASCII art now I understand this part...Code:procedure TBlurp.DoMove(TimeGap: Double); var cnrs: TCorners; begin inherited; cnrs := Form1.GetCorners(self); if vy < 0 then // moving up begin if (not cnrs.WallUL) and (not cnrs.WallUR) then // not obstructed so move normally y := y + vy * TimeGap else // hit tile so move to edge of tile and stop begin vy := 0; y := cnrs.Up * cTileH + cTileH + 16; end; end else if vy > 0 then // moving down begin if (not cnrs.WallDL) and (not cnrs.WallDR) then // not obstructed so move normally y := y + vy * TimeGap else // hit tile so move to edge of tile and stop begin vy := 0; y := cnrs.Down * cTileH - 16; end; end; cnrs := Form1.GetCorners(self); if vx < 0 then // moving left begin if (not cnrs.WallUL) and (not cnrs.WallDL) then // not obstructed so move normally x := x + vx * TimeGap else // hit tile so move to edge of tile and stop begin vx := 0; x := cnrs.Left * cTileW + cTileW + 16; end; end else if vx > 0 then // moving right begin if (not cnrs.WallUR) and (not cnrs.WallDR) then // not obstructed so move normally x := x + vx * TimeGap else // hit tile so move to edge of tile and stop begin vx := 0; x := cnrs.Right * cTileW - 16; end; end; // Collision; end;
Problem : stops a bit further then it should LEFT and TOP, and to late RIGHT and BOTTOM, it's like the calulation is OK but Offset.Code:function TForm1.GetCorners(aSpr: TSprite): TCorners; // get object corners, includes velocity! begin // calculate tile index for each object corner Result.Left := Math.Floor((aSpr.x -16 + Blurp.vx) / cTileW); Result.Right := Math.Floor((aSpr.x + 16 + Blurp.vx) / cTileW); Result.Up := Math.Floor((aSpr.y -16 + Blurp.vy) / cTileH); Result.Down := Math.Floor((aSpr.y + 16 + Blurp.vy) / cTileH); // if true then there is a wall there Result.WallUL := WallAt(Result.Left ,Result.Up); Result.WallUR := WallAt(Result.Right ,Result.Up); Result.WallDL := WallAt(Result.Left ,Result.Down); Result.WallDR := WallAt(Result.Right ,Result.Down); end;
During testing I've commented out the lines that "should" put my character right beside the wall if there is a hit... because that to is working in an unexpected way.
Attached is my latest source code, meanwhile I'll play with it... hopefully I'm manipulating the vx and vy in a correct way.
test.zip
Greetings
Rob
I DID IT !!!!
Without your help i wouldn't get this far this soon... but it still feels kinda good
for some reason, and I will need to figure it out why... Left and UP works if instead of - I do + Image.Widht/2 and + Image.Height/2Code:Result.Left := Math.Floor((x +(Image.Width/2) + vx) / cTileW); Result.Right := Math.Floor((x + (Image.Width/2) + vx) / cTileW); Result.Up := Math.Floor((y + (Image.Height/2) + vy) / cTileH); Result.Down := Math.Floor((y + (Image.Height/2) + vy) / cTileH);
Now I can go to the wall everywhere...there is one small bug... with any direction if I have a single WALL in center or anywhere...where I can move around it...
my character can anter this WALL from LEFT or RIGHT if my character is HIGHER or LOWER then this WALL by more then my Characters own Height/2.
C is character points , X is wall... can move inside wall... but only if I touch it like that... UP DOWN, LEFT and RIGHT works...
Code:CC CCXX XXX CCXX CC
Same thing happens for UP and DOWN... my Character can enter the WALL from UP and DOWN if it's LEFT or RIGHT side is free by more then its Width/2.
(hopefully I've managed to write this down and someone understand's this... my english might be bad)
Regarding the vx and vy ... I've studied a few demos..samples... I know it works...now, but was wondering if I'm doing this the right way, the way it was meant to be done in Andorra 2d (or if this is not specific to just this engine... then any other engine).
Damn... was to soon to say... It seems if I change...vx or vy to other value... it does not work correctly...guess this only works cause I made a "lucky" bug
Greetings
Robert
Last edited by robert83; 18-08-2011 at 03:33 PM. Reason: is vx and vy set correctly?
You cannot simply change + and - anywhere when you like. Does it look logical? For that case Left and Up must be - . You can see this by looking at what the function returns. It returns the area where sprite is. If both were + it would result a simple dot that is located in down right corner of sprite, for + and - it is a rectangle all around player sprite what was wanted. So bugs are still elsewhere.
Also, you are using vx and vy varibles in GetCorners() function without multiplying it with TimeGap.
That's great news
I realised I forgot to mention these facts which are kind of crucial
With the code I gave you, the world coordinate system I was working has the origin at the top left of the screen, so:
left = -movement
right = +movement
up = -movement
down = +movement
so you need to match the +/- with your Adorra 2d screen coordinate system.
Since you said left and up now seem to work using + instead of - as in my example then I would guess you need to use this now:
does this change things?Code:Result.Left := Math.Floor((x +(Image.Width/2) + vx) / cTileW); Result.Right := Math.Floor((x - (Image.Width/2) + vx) / cTileW); Result.Up := Math.Floor((y + (Image.Height/2) + vy) / cTileH); Result.Down := Math.Floor((y - (Image.Height/2) + vy) / cTileH);
cheers,
Paul
Games:
Seafox
Pages:
Syntax Error Software
itch.io page
Online Chess
http://gameknot.com/#paul_nicholls
Hello,
Thank you Paul for the suggestion... I guess in my confusion I confused you as well sorry... Andorra 2d also top left origin... anyway I was banging my head against the wall the whole day (probably overcomplicating something that is not that complex...) . I've decided I give a try to what Traveler said before... to include direction in my testforwall function. And this time (kinda like a wonder) it really works :
TestWall function
controlling of characterCode:function TBlurp.testForWall(spriteXpos,spriteYpos:single;spriteWidth,spriteHeight:integer;direction:string):boolean; begin testForWall := false; if direction = 'left' then begin if not (TileInfo[round(spriteXpos) div 64, round(spriteYpos) div 64].tilenr in [2]) or not (TileInfo[round(spriteXpos)div 64, (round(spriteYpos)+spriteHeight) div 64].tilenr in [2]) then testForWall := true; end; if direction = 'right' then begin if not(TileInfo[(round(spriteXpos)+spriteWidth) div 64, round(spriteYpos) div 64].tilenr in [2]) or not (TileInfo[(round(spriteXpos)+spriteWidth) div 64, (round(spriteYpos)+spriteHeight) div 64].tilenr in [2]) then testForWall :=true; end; if direction = 'up' then begin if not (TileInfo[round(spriteXpos) div 64, round(spriteYpos) div 64].tilenr in [2]) or not (TileInfo[(round(spriteXpos)+spriteWidth) div 64, round(spriteYpos) div 64].tilenr in [2]) then testForWall :=true; end; if direction = 'down' then begin if not (TileInfo[round(spriteXpos)div 64, (round(spriteYpos)+spriteHeight) div 64].tilenr in [2]) or not (TileInfo[(round(spriteXpos)+spriteWidth) div 64, (round(spriteYpos)+spriteHeight) div 64].tilenr in [2]) then testForWall :=true; end; end;
Right now I'm doing the movement onIdle of TFORM ... which means I'm not using TimeGap for movement... which is bad I know, I just wanted to make it real simple for now (so that I can sleep well, that atleast I've acomplished half of what I wanted).... tomorrow I'll modify my code so that the movement is done in the Sprites.OnMove , and I only give x or y velocity here...Code:ActTime := ActTime + AdPerCounter.TimeGap; if ActTime > 25 then begin if GetKeyState(VK_LEFT) < 0 then begin if not Blurp.testForWall(Blurp.X-4,Blurp.Y,Blurp.Image.Width,Blurp.Image.Height-1,'left') then begin Blurp.X:=Blurp.X-4; AdSpriteEngine.X:=AdSpriteEngine.X+4; end; end; if GetKeyState(VK_RIGHT) < 0 then begin if not Blurp.testForWall(Blurp.X,Blurp.Y,Blurp.Image.Width,Blurp.Image.Height-1,'right') then begin Blurp.X:=Blurp.X+4; AdSpriteEngine.X:=AdSpriteEngine.X-4; end; end; if GetKeyState(VK_UP) < 0 then begin if not Blurp.testForWall(Blurp.X,Blurp.Y-4,Blurp.Image.Width-1,Blurp.Image.Height,'up') then begin Blurp.Y:=Blurp.Y-4; AdSpriteEngine.Y:=AdSpriteEngine.Y+4; end; end; if GetKeyState(VK_DOWN) < 0 then begin if not Blurp.testForWall(Blurp.X,Blurp.Y,Blurp.Image.Width-1,Blurp.Image.Height,'down') then begin Blurp.Y:=Blurp.Y+4; AdSpriteEngine.Y:=AdSpriteEngine.Y-4; end; end; ActTime := 0; end;
Anyway I've attached my code with the compiled executable, if I may ask you to please test it, it works. And I'm hoping it works just as well as the one you've suggested. (multiple solutions for the same problem).
egyszeru 7 5-os maskepp.zip
Greetings
Rob
It works for me just fine (after I downloaded the missing directx dll (d3dx9_33.dll)...the last version I tried needed the d3dx9_31.dll version for some reason?
I was thinking...if go for the opengl version dll for Andorra 2d, then your game (when finished) could be cross-platform...just a thought, and my $0.02
cheers,
Paul
Games:
Seafox
Pages:
Syntax Error Software
itch.io page
Online Chess
http://gameknot.com/#paul_nicholls
Hi,
I was playing a bit further with my program, and modified so I do the movement in the SpriteEngine.DoMove procedure , and it works fine regardles if velocity is 80, 95, or whatever... what I modified compared to my older source is :
TForm1.OnIDLE
Here is one obvious problem, which I did not even tried to solve... for now, somehow my Figure moves faster then the
screen is scroll. ( I was hoping the speed would be the same...but there is a slight difference... will play with it later... was not
the object here to solve that ... but rather to implement the movement more properly)
Here Is my modified DoMove , for now works great, been playing with it , using different velocity... always stops where it should yippeeeCode:ActTime := ActTime + AdPerCounter.TimeGap; if ActTime > 25 then begin Blurp.vx:=0; Blurp.vy:=0; if GetKeyState(VK_LEFT) < 0 then begin Blurp.vx:=-95; AdSpriteEngine.X:=AdSpriteEngine.X-Blurp.vx*(AdPerCounter.TimeGap/1000); end; if GetKeyState(VK_RIGHT) < 0 then begin Blurp.vx:=95; AdSpriteEngine.X:=AdSpriteEngine.X-Blurp.vx*(AdPerCounter.TimeGap/1000); end; if GetKeyState(VK_UP) < 0 then begin Blurp.vy:=-95; AdSpriteEngine.Y:=AdSpriteEngine.Y-Blurp.vy*(AdPerCounter.TimeGap/1000); end; if GetKeyState(VK_DOWN) < 0 then begin Blurp.vy:=95; AdSpriteEngine.Y:=AdSpriteEngine.Y-Blurp.vy*(AdPerCounter.TimeGap/1000); end; ActTime := 0; end;
Also one unexpected sidefect is ... before it was important where my Start position for my character was... now it's not , X can be 128,139,131 ... it works the same.Code:procedure TBlurp.DoMove(TimeGap: Double); begin inherited; // left if vx < 0 then begin if not testForWall(X+vx*TimeGap,Y,Image.Width,Image.Height-1,'left') then begin X:=X+round(vx*TimeGap) ; end; end; // right if vx > 0 then begin if not testForWall(X,Y,Image.Width,Image.Height-1,'right') then begin X:=X+round(vx*TimeGap); end; end; // up if vy < 0 then begin if not testForWall(X,Y+vy*TimeGap,Image.Width-1,Image.Height,'up') then begin Y:=Y+round(vy*TimeGap); end; end; // down if vy > 0 then begin if not testForWall(X,Y,Image.Width-1,Image.Height,'down') then begin Y:=Y+round(vy*TimeGap); end; end; Collision; end;
Anyway I'll continue now with implementing gravity And checking the scrolling part.
Greetings
Rob
Bookmarks