Zeige Ergebnis 1 bis 22 von 22

GUIDE: Collisions

This is a discussion on GUIDE: Collisions within the PSP Development Forum forums, part of the PSP Development, Hacks, and Homebrew category; I made this tutorial because I've seen a lot of people having problems with collisions in their games , and ...

  
  1. #1
    Points: 4.492, Level: 42
    Level completed: 72%, Points required for next Level: 58
    Overall activity: 0%

    Registriert seit
    Nov 2005
    Ort
    Minnesota, USA.
    Beiträge
    36
    Points
    4.492
    Level
    42
    Downloads
    0
    Uploads
    0

    Smile GUIDE: Collisions

    I made this tutorial because I've seen a lot of people having problems with collisions in their games, and a lot of requests for a guide.

    GUIDE:

    Lets say that you want to make a game where you have 2 squares, one for the player and one for the enemy, and both of the squares are 32 pixels in height and length. You want the enemy square to constantly move back and forth jumping randomly, and for the player square to move when you press the D-dad and jump when you press X. The code for that would look something like this (disregard the extra spaces inserted by the forums):

    Code:
     
    system.usbDiskModeActivate() 
     
    red = Color.new(255,0,0)
    black = Color.new(0,0,0)
    blue = Color.new(0,0,255)
    black = Color.new(0,0,0)
     
    leftorright = 2
     
    player1 = Image.createEmpty(32,32)
    ground = Image.createEmpty(480,10)
    sky = Image.createEmpty(480,262)
    enemy1 = Image.createEmpty(32,32)
     
    player1:clear(red)
    sky:clear(blue)
    ground:clear(black)
    enemy1:clear(red)
     
    player = {}
    player.y = 230
    player.x = 50
    player.jumpspeed = 10
    player.jumpstate = "ground"
    player.gravity = 230
     
    enemy = {}
    enemy.y = 230
    enemy.x = 430
    enemy.jumpspeed = 10
    enemy.jumpstate = "ground"
    enemy.gravity = 230
     
    while true do
     
    pad = Controls.read()
     
    screen:clear()
     
    if pad:left() then
    player.x = player.x - 2
    end
     
    if pad:right() then
    player.x = player.x + 2
    end
     
    if (pad:cross()) and (player.jumpstate == "ground") then
    player.jumpstate = "jumping"
    end
     
    if (enemy.x == math.random(20,420)) and (enemy.jumpstate == "ground") then
    enemy.jumpstate = "jumping"
    end
     
    if (enemy.x == math.random(5,420)) and (enemy.jumpstate == "ground") then
    enemy.jumpstate = "jumping"
    end
     
    if (enemy.x == math.random(10,420)) and (enemy.jumpstate == "ground") then
    enemy.jumpstate = "jumping"
    end
     
    if (enemy.x == math.random(20,400)) and (enemy.jumpstate == "ground") then
    enemy.jumpstate = "jumping"
    end
     
    if (enemy.x == math.random(15,430)) and (enemy.jumpstate == "ground") then
    enemy.jumpstate = "jumping"
    end
     
    if (player.jumpstate == "jumping") then
    player.jumpspeed = player.jumpspeed - 0.5
    player.gravity = player.gravity - player.jumpspeed
    end
     
    if (enemy.jumpstate == "jumping") then
    enemy.jumpspeed = enemy.jumpspeed - 0.5
    enemy.gravity = enemy.gravity - enemy.jumpspeed
    end
     
    if (player.gravity < 0) then
    player.jumpstate = "falling"
    end
     
    if (enemy.gravity < 0) then
    enemy.jumpstate = "falling"
    end
     
    if (player.gravity < 230) and (player.jumpstate == "falling") then
    player.gravity = player.gravity + (player.jumpspeed + 3)
    end
     
    if (enemy.gravity < 230) and (enemy.jumpstate == "falling") then
    enemy.gravity = enemy.gravity + (enemy.jumpspeed + 3)
    end
     
    if (player.gravity == 230) then
    player.jumpspeed = 10
    player.jumpstate = "ground"
    end
     
    if (enemy.gravity == 230) then
    enemy.jumpspeed = 10
    enemy.jumpstate = "ground"
    end
     
    if (player.gravity > 230) then
    player.gravity = 230
    end
     
    if (enemy.gravity > 230) then
    enemy.gravity = 230
    end
     
    if (enemy.x == 448) then
    leftorright = 1
    end
     
    if (enemy.x == 0) then
    leftorright = 2
    end
     
    if (player.x == 448) then
    player.x = player.x - 2
    end
     
    if (player.x == 0) then
    player.x = player.x + 2
    end
     
    if (leftorright == 1) then
    enemy.x = enemy.x - 2
    end
     
    if (leftorright == 2) then
    enemy.x = enemy.x + 2
    end
     
    if pad:start() then
    break
    end
     
    player.y = player.gravity
    enemy.y = enemy.gravity
     
    screen:blit(0,0,sky)
    screen:blit(0,262,ground)
    screen:blit(player.x,player.y,player1)
    screen:blit(enemy.x,enemy.y,enemy1)
     
    screen.waitVblankStart()
     
    screen.flip()
     
    end
    At this point of the game the two squares would pass right over each other without doing anything. This is because there is no collision detection. Here are a few things that you should know about the player1 and enemy1 images and collision detection:
    1. The "player.x" and the "player.y" variables both refer to the pixel located at the top left-hand corner of the player1 image created (this is the point at which the PSP screen displayes the first pixel of the image).
    2. The "enemy.x" and the "enemy.y" variables both refer to the pixel located at the top left-hand corner of the enemy1 image created (this is the point at which the PSP screen displayes the first pixel of the image).
    3. In order to use collision detection, you must have the pixel coordinates of all but one of the corners (right now we only have one of them).
    Here's is a picture of what the coordinates for the corners would be.

    http://img217.imageshack.us/my.php?image=corners8aw.png

    Ok, here is the actual collision detection part.

    You obviously want to find out when and if any part of the player1 image touches any part of the enemy1 image. First we have to add these to the player and enemy arrays:

    Code:
     
    player.y32 = player.y + 32 --This is the bottom left-hand corner of player1
    player.x32 = player.x + 32 --This is the top right-hand corner of player1
    enemy.y32 = enemy.y + 32 --This is the bottom left-hand corner of enemy1
    enemy.x32 = enemy.x + 32 --This is the top right-hand corner of enemy1
    Now, using the corner coordinates we can create this if statement:

    Code:
     
    if (((player.x32 >= enemy.x) and (player.x <= enemy.x32)) and ((player.y32 >= enemy.y) and (player.y <= enemy.y32))) then
    break
    end
    Basically what this if statement is saying is this.

    "If the corners of the player1 image are in the same space as the enemy1 corners than exit the program"

    Here is another picture of the corners, except this one is to disect the if statement.

    http://img227.imageshack.us/my.php?i...cations3ow.png

    I know that it may look/sound confusing at first (at least it did to me), but just go back and look at the corners image and the if statement, study them for a while, and I think that you will get it.



    If anybody sees any errors in my tutorial please point them out and I will gladly change it.

    NOTE: This is my first tutorial, and i'm not a very experienced coder. So, please be nice :icon_smil with the comments and such.


    Geändert von Jeffery (04-13-2006 um 04:09 AM Uhr)

  2. #2
    TheMarioKarters
    Guest

    Standard

    Wow, nice tut. Will help a lot of folks.

  3. #3
    Quality Haxing Since 1991
    Points: 29.255, Level: 99
    Level completed: 55%, Points required for next Level: 745
    Overall activity: 0%

    Registriert seit
    Oct 2005
    Ort
    Pennsylvania, USA Fi
    Beiträge
    6.206
    Points
    29.255
    Level
    99
    Downloads
    0
    Uploads
    0

    Standard

    Awesome! Thanks for taking the time to make all this man.
    Zitat Zitat von Noriko
    I would call you gay but I love you.


    Wait ...huh.



  4. #4
    Developer
    Points: 8.360, Level: 61
    Level completed: 70%, Points required for next Level: 90
    Overall activity: 16,0%

    Registriert seit
    Jun 2005
    Ort
    At my house...
    Beiträge
    886
    Points
    8.360
    Level
    61
    Downloads
    0
    Uploads
    0

    Standard

    Zitat Zitat von TheMarioKarters
    Wow, nice tut. Will help a lot of folks.
    Like you xD

  5. #5
    QJ Gamer Blue
    Points: 4.816, Level: 44
    Level completed: 33%, Points required for next Level: 134
    Overall activity: 0%

    Registriert seit
    Apr 2006
    Beiträge
    301
    Points
    4.816
    Level
    44
    Downloads
    0
    Uploads
    0

    Standard

    the code is fine except the colors you defined don't really match the colors you assigned to the objects.
    Code:
     
    system.usbDiskModeActivate() 
     
    red = Color.new(255,0,0)
    black = Color.new(0,0,0)
    blue = Color.new(0,0,255)
    black = Color.new(0,0,0)
     
    leftorright = 2
     
    player1 = Image.createEmpty(32,32)
    ground = Image.createEmpty(480,10)  
    sky = Image.createEmpty(480,262  )
    enemy1 = Image.createEmpty(32,32)
     
    player1:clear(red)
    sky:clear(blue)
    ground:clear(black)
    enemy1:clear(red)
     
    player = {}
    player.y = 230
    player.x = 50
    player.jumpspeed = 10
    player.jumpstate = "ground"
    player.gravity = 230
     
    enemy = {}
    enemy.y = 230
    enemy.x = 430
    enemy.jumpspeed = 10
    enemy.jumpstate = "ground"
    enemy.gravity = 230
     
    while true do
     
    pad = Controls.read()
     
    screen:clear()
     
    if pad:left() then
    player.x = player.x - 2
    end
     
    if pad:right() then
    player.x = player.x + 2
    end
     
    if (pad:cross()) and (player.jumpstate == "ground") then
    player.jumpstate = "jumping"
    end
     
    if (enemy.x == math.random(20,420)) and (enemy.jumpstate == "ground") then
    enemy.jumpstate = "jumping"
    end
     
    if (enemy.x == math.random(5,420)) and (enemy.jumpstate == "ground") then
    enemy.jumpstate = "jumping"
    end
     
    if (enemy.x == math.random(10,420)) and (enemy.jumpstate == "ground") then
    enemy.jumpstate = "jumping"
    end
     
    if (enemy.x == math.random(20,400)) and (enemy.jumpstate == "ground") then
    enemy.jumpstate = "jumping"
    end
     
    if (enemy.x == math.random(15,430)) and (enemy.jumpstate == "ground") then
    enemy.jumpstate = "jumping"
    end
     
    if (player.jumpstate == "jumping") then
    player.jumpspeed = player.jumpspeed - 0.5
    player.gravity = player.gravity - player.jumpspeed
    end
     
    if (enemy.jumpstate == "jumping") then
    enemy.jumpspeed = enemy.jumpspeed - 0.5
    enemy.gravity = enemy.gravity - enemy.jumpspeed
    end
     
    if (player.gravity < 0) then
    player.jumpstate = "falling"
    end
     
    if (enemy.gravity < 0) then
    enemy.jumpstate = "falling"
    end
     
    if (player.gravity < 230) and (player.jumpstate == "falling") then
    player.gravity = player.gravity + (player.jumpspeed + 3)
    end
     
    if (enemy.gravity < 230) and (enemy.jumpstate == "falling") then
    enemy.gravity = enemy.gravity + (enemy.jumpspeed + 3)
    end
     
    if (player.gravity == 230) then
    player.jumpspeed = 10
    player.jumpstate = "ground"
    end
     
    if (enemy.gravity == 230) then
    enemy.jumpspeed = 10
    enemy.jumpstate = "ground"
    end
     
    if (player.gravity > 230) then
    player.gravity = 230
    end
     
    if (enemy.gravity > 230) then
    enemy.gravity = 230
    end
     
    if (enemy.x == 448) then
    leftorright = 1
    end
     
    if (enemy.x == 0) then
    leftorright = 2
    end
     
    if (player.x == 448) then
    player.x = player.x - 2
    end
     
    if (player.x == 0) then
    player.x = player.x + 2
    end
     
    if (leftorright == 1) then
    enemy.x = enemy.x - 2
    end
     
    if (leftorright == 2) then
    enemy.x = enemy.x + 2
    end
     
    if pad:start() then
    break
    end
     
    player.y = player.gravity
    enemy.y = enemy.gravity
     
    screen:blit(0,0,sky)
    screen:blit(0,262,ground)  
    screen:blit(player.x,player.y,player1)
    screen:blit(enemy.x,enemy.y,enemy1)
     
    screen.waitVblankStart()
     
    screen.flip()
     
    end
    other than that, the code is fine

  6. #6
    QJ Gamer Blue
    Points: 4.890, Level: 44
    Level completed: 70%, Points required for next Level: 60
    Overall activity: 0%

    Registriert seit
    Mar 2006
    Beiträge
    338
    Points
    4.890
    Level
    44
    Downloads
    0
    Uploads
    0

    Standard

    this is a great guide and should be a sticky. I have a ton of problems with collisions and this helps a lot

  7. #7
    QJ Gamer Bronze
    Points: 8.803, Level: 63
    Level completed: 18%, Points required for next Level: 247
    Overall activity: 0%

    Registriert seit
    Jan 2006
    Ort
    Western Australia
    Beiträge
    1.046
    Points
    8.803
    Level
    63
    Downloads
    0
    Uploads
    0

    Standard

    Yay, you made many people happy.

  8. #8
    QJ Gamer Bronze
    Points: 4.362, Level: 42
    Level completed: 6%, Points required for next Level: 188
    Overall activity: 0%

    Registriert seit
    Apr 2006
    Ort
    germany
    Beiträge
    38
    Points
    4.362
    Level
    42
    Downloads
    0
    Uploads
    0

    Standard my own code

    if you're interested, here's my own code (borrowed a bit from ps2dev

    Code:
    function detect_collision(enemyX,enemyY,enemyWidth,enemyHeight)
    
    --attack area
    
    --		x1---x2	
    --		|     |   player	
    --		|  X  |   X=centre
    --		|     |	--> collision when centre is hit by centre of enemy
    --		y1---y2	
    
    collision=1
    
    x1=xpos
    x2=xpos+playerWidth
    y1=ypos
    y2=ypos+playerHeight
    
    e_x1=enemyX
    e_x2=enemyX+enemyWidth
    e_y1=enemyY
    e_y2=enemyY+enemyHeight
    
    x_centre=xpos+( (x2-x1)/2 )
    y_centre=ypos+( (y2-y1)/2 )
    
    e_x_centre=enemyX+( (e_x2-e_x1)/2 )
    e_y_centre=enemyY+( (e_y2-e_y1)/2 )
    
    
    if math.abs(e_x_centre-x_centre)>=enemyWidth/2		then collision=0
    elseif math.abs(e_y_centre-y_centre)>=enemyHeight/2	then collision=0 
    end
    
    return collision
    
    end
    if not, delete :P
    -=imhotep=-

  9. #9
    Points: 4.063, Level: 40
    Level completed: 57%, Points required for next Level: 87
    Overall activity: 0%

    Registriert seit
    Mar 2006
    Beiträge
    7
    Points
    4.063
    Level
    40
    Downloads
    0
    Uploads
    0

    Standard

    I don't understand how people think collisions are so difficult. I just hate when if it's going too fast, and it overlaps. I've found ways around that, though. :]

  10. #10
    QJ Gamer Gold
    Points: 13.240, Level: 74
    Level completed: 98%, Points required for next Level: 10
    Overall activity: 0%

    Registriert seit
    May 2005
    Ort
    I live in a City that goes by the nickname:The Bubble. 'Nuff said.
    Beiträge
    1.766
    Points
    13.240
    Level
    74
    Downloads
    0
    Uploads
    0

    Standard

    STICKY PLEASE.

    Great job on the tut, man!

  11. #11
    Developer
    Points: 6.074, Level: 50
    Level completed: 62%, Points required for next Level: 76
    Overall activity: 0%

    Registriert seit
    Sep 2005
    Beiträge
    270
    Points
    6.074
    Level
    50
    Downloads
    0
    Uploads
    0

    Standard

    Thank you for this!

  12. #12
    Points: 4.492, Level: 42
    Level completed: 72%, Points required for next Level: 58
    Overall activity: 0%

    Registriert seit
    Nov 2005
    Ort
    Minnesota, USA.
    Beiträge
    36
    Points
    4.492
    Level
    42
    Downloads
    0
    Uploads
    0

    Standard

    :icon_smil Thanks for all of the comments guys. (BTW: These forums are the best!)

  13. #13
    QJ Gamer Gold
    Points: 18.627, Level: 86
    Level completed: 56%, Points required for next Level: 223
    Overall activity: 0%

    Registriert seit
    Mar 2006
    Ort
    LOLWUT
    Beiträge
    2.625
    Points
    18.627
    Level
    86
    Downloads
    0
    Uploads
    0

    Smile Great tutorial!

    Thank you so much! This should definetly be a sticky since people constantly ask about collision detection.

  14. #14
    Is in your zone.
    Points: 24.342, Level: 94
    Level completed: 99%, Points required for next Level: 8
    Overall activity: 0%

    Registriert seit
    Oct 2005
    Ort
    Jacksonville, FL
    Beiträge
    3.429
    Points
    24.342
    Level
    94
    Downloads
    0
    Uploads
    0

    Standard

    Instead of using player.x n player.y can I use variable I already have like cursorx and cursory?

    --XBL Gamertag: PhenoM904--

  15. #15
    Points: 4.492, Level: 42
    Level completed: 72%, Points required for next Level: 58
    Overall activity: 0%

    Registriert seit
    Nov 2005
    Ort
    Minnesota, USA.
    Beiträge
    36
    Points
    4.492
    Level
    42
    Downloads
    0
    Uploads
    0

    Standard

    I think that you could do that. Just replace the "player.y32 = player.y + 32" and "player.x32 = player.x + 32" with "curserxcorner = cursorx + (width of the cursor)" and "curserycorner = cursory + (height of the cursor)".

    Let me know if that works. :icon_smil

  16. #16
    Mindless Fanboy
    Points: 17.218, Level: 83
    Level completed: 74%, Points required for next Level: 132
    Overall activity: 0%

    Registriert seit
    Mar 2006
    Beiträge
    1.907
    Points
    17.218
    Level
    83
    Downloads
    0
    Uploads
    0

    Standard

    this better get stickied

  17. #17
    QJ Gamer Green
    Points: 5.559, Level: 48
    Level completed: 5%, Points required for next Level: 191
    Overall activity: 0%

    Registriert seit
    Jan 2006
    Beiträge
    506
    Points
    5.559
    Level
    48
    Downloads
    0
    Uploads
    0

    Standard

    Zitat Zitat von MaSt3r_ShAk3
    Instead of using player.x n player.y can I use variable I already have like cursorx and cursory?
    That definately works
    LUA manual:
    [url]http://www.lua.org/manual/5.0/manual.html[/url]

    LUA Wiki:
    [url]http://wiki.ps2dev.org/psp:lua_player[/url]

  18. #18
    sceKernelExitGame();
    Points: 19.955, Level: 89
    Level completed: 21%, Points required for next Level: 395
    Overall activity: 0%

    Registriert seit
    Jan 2006
    Ort
    New York
    Beiträge
    3.126
    Points
    19.955
    Level
    89
    Downloads
    0
    Uploads
    0

    Standard

    thanks man!

  19. #19
    QJ Gamer Green
    Points: 6.920, Level: 54
    Level completed: 85%, Points required for next Level: 30
    Overall activity: 0%

    Registriert seit
    May 2006
    Ort
    Programming or Farming Mudkips
    Beiträge
    657
    Points
    6.920
    Level
    54
    Downloads
    0
    Uploads
    0

    Standard

    meh, it's just lua. Charlie from EvilMana already made tut about tutorials. But that's beside the fact that C++ is so much better :Punk:
    Current Project: Citrus

  20. #20
    sceKernelExitGame();
    Points: 19.955, Level: 89
    Level completed: 21%, Points required for next Level: 395
    Overall activity: 0%

    Registriert seit
    Jan 2006
    Ort
    New York
    Beiträge
    3.126
    Points
    19.955
    Level
    89
    Downloads
    0
    Uploads
    0

    Standard

    thanks a lot!

  21. #21
    words are stones in my <3
    Points: 35.274, Level: 100
    Level completed: 0%, Points required for next Level: 0
    Overall activity: 0%

    Registriert seit
    Jul 2005
    Ort
    Spokane
    Beiträge
    5.008
    Points
    35.274
    Level
    100
    My Mood
    Lonely
    Downloads
    1
    Uploads
    0

    Standard

    ... Why not use my function for collision? it totally saves a billion lines, not to mention takes 1 line to actually check for collision... but whatever, awesome to see this done on a more specific app.

    ...at what speed must I live.. to be able to see you again?...

    Projects

    You can support my Open World 3D RPG for PSP by voting for it here


  22. #22
    sceKernelExitGame();
    Points: 19.955, Level: 89
    Level completed: 21%, Points required for next Level: 395
    Overall activity: 0%

    Registriert seit
    Jan 2006
    Ort
    New York
    Beiträge
    3.126
    Points
    19.955
    Level
    89
    Downloads
    0
    Uploads
    0

    Standard

    Zitat Zitat von SG57
    ... Why not use my function for collision? it totally saves a billion lines, not to mention takes 1 line to actually check for collision... but whatever, awesome to see this done on a more specific app.
    dont worry, i'll read both ;)


 

Tags for this Thread

Forumregeln

  • Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
  • Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
  • Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
  • Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
  •  





Alle Zeitangaben in WEZ -8. Es ist jetzt 09:00 PM Uhr.

Use of this Web site constitutes acceptance of the TERMS & CONDITIONS and PRIVACY POLICY
Copyright © , Caputo Media, LLC. All Rights Reserved. Cluster .