Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   NPC Scripting (https://forums.graalonline.com/forums/forumdisplay.php?f=8)
-   -   Collision check script error (https://forums.graalonline.com/forums/showthread.php?t=134265607)

iBeatz 01-22-2012 06:39 PM

Collision check script error
 
I'm having a problem constructing collision checks for a replica of the classic Pong game.
I'll post all of the code before I explain the problem:

PHP Code:

//#CLIENTSIDE

const BALL_SPEED 6;

function 
onWeaponFired(){

  
this.game_active = !this.game_active;

  if(
this.game_active){
    
onInitiatePong();
  }
  else {
    
onClosePong();
  }
}

function 
onInitiatePong(){

  
// Scaling of game screen and objects
  
temp.court_width 500;
  
temp.court_height 350;
  
temp.paddle_width 20;
  
temp.paddle_height 100;
  
temp.ball_width 16;
  
temp.ball_height 16;

  
// Black background
  
showPoly(1000, {(screenwidth/2)-(temp.court_width/2), (screenheight/2)-(temp.court_height/2),
                  (
screenwidth/2)+(temp.court_width/2), (screenheight/2)-(temp.court_height/2),
                  (
screenwidth/2)+(temp.court_width/2), (screenheight/2)+(temp.court_height/2),
                  (
screenwidth/2)-(temp.court_width/2), (screenheight/2)+(temp.court_height/2)});
  
changeImgColors(10000001);
  
changeImgVis(10005);
  
  
// Left white paddle
  
showPoly(1001, {(screenwidth/2)-(temp.court_width/2)+10, (screenheight/2)-(temp.paddle_height/2),
                  (
screenwidth/2)-(temp.court_width/2)+10+temp.paddle_width, (screenheight/2)-(temp.paddle_height/2),
                  (
screenwidth/2)-(temp.court_width/2)+10+temp.paddle_width, (screenheight/2)+(temp.paddle_height/2),
                  (
screenwidth/2)-(temp.court_width/2)+10, (screenheight/2)+(temp.paddle_height/2)});
  
changeImgColors(10011111);
  
changeImgVis(10016);
  
  
// Right white paddle
  
showPoly(1002, {(screenwidth/2)+(temp.court_width/2)-10, (screenheight/2)-(temp.paddle_height/2),
                  (
screenwidth/2)+(temp.court_width/2)-10-temp.paddle_width, (screenheight/2)-(temp.paddle_height/2),
                  (
screenwidth/2)+(temp.court_width/2)-10-temp.paddle_width, (screenheight/2)+(temp.paddle_height/2),
                  (
screenwidth/2)+(temp.court_width/2)-10, (screenheight/2)+(temp.paddle_height/2)});
  
changeImgColors(10021111);
  
changeImgVis(10026);
  
  
// Central white divider
  
showPoly(1003, {(screenwidth/2), (screenheight/2)-(temp.court_height/2),
                  (
screenwidth/2), (screenheight/2)+(temp.court_height/2)-1});
  
changeImgColors(10031111);
  
changeImgVis(10036);
  
  
// Centre-starting ball
  
showPoly(1004, {(screenwidth/2)-(temp.ball_width/2), (screenheight/2)-(temp.ball_height/2),
                  (
screenwidth/2)+(temp.ball_width/2), (screenheight/2)-(temp.ball_height/2),
                  (
screenwidth/2)+(temp.ball_width/2), (screenheight/2)+(temp.ball_height/2),
                  (
screenwidth/2)-(temp.ball_width/2), (screenheight/2)+(temp.ball_height/2)});
  
changeImgColors(10041111);
  
changeImgVis(10047);
  
  
scheduleEvent(0.5"StartPong"NULL);
}

function 
onStartPong(){

  
temp.ball_angle random(0360);
  
  
onMoveBall(temp.ball_angle);
}

function 
onMoveBall(temp.angle){

  
cancelEvents("MoveBall");
  
  if(
int(temp.angle 90) == 0){
    
temp.angle += random(-1010);
  }
  
  
// Ball collision detection and angle adjustment
  
for(temp.iy 1temp.iy <= 7temp.iy += 2){
    if(
findImg(1004).polygon[temp.iy] - cos(degtorad(temp.angle)) * BALL_SPEED findImg(1000).polygon[1] ||
      
findImg(1004).polygon[temp.iy] - cos(degtorad(temp.angle)) * BALL_SPEED findImg(1000).polygon[7]){
      
temp.angle 180 temp.angle;
    }
    
// First collision check
    
if(findImg(1004).polygon[temp.iy-1] + sin(degtorad(temp.angle)) * BALL_SPEED in |findImg(1001).polygon[0], findImg(1001).polygon[2]|){
      if(
findImg(1004).polygon[temp.iy] - cos(degtorad(temp.angle)) * BALL_SPEED in |findImg(1001).polygon[7]-10findImg(1001).polygon[7]| ||
        
findImg(1004).polygon[temp.iy] - cos(degtorad(temp.angle)) * BALL_SPEED in |findImg(1001).polygon[1], findImg(1001).polygon[1]+10|){
        
temp.angle 180 temp.angle;
      }
      
// Second collision check
      // MY PROBLEM IS THE LINE BELOW
      
else if(findImg(1004).polygon[temp.iy] - cos(degtorad(temp.angle)) * BALL_SPEED in |findImg(1002).polygon[7]-10findImg(1002).polygon[7]| ||
        
findImg(1004).polygon[temp.iy] - cos(degtorad(temp.angle)) * BALL_SPEED in |findImg(1002).polygon[1], findImg(1002).polygon[1]+10|){
        
temp.angle 180 temp.angle;
      }
    }
  }
  
  
// Moving the ball along angle
  
for(temp.bx 0temp.bx <= 6temp.bx += 2){
    
findImg(1004).polygon[temp.bx] += sin(degtorad(temp.angle)) * BALL_SPEED;
  }
  for(
temp.by 1temp.by <= 7temp.by += 2){
    
findImg(1004).polygon[temp.by] -= cos(degtorad(temp.angle)) * BALL_SPEED;
  }
  
  
showText(1005findImg(1004).polygon[0], findImg(1004).polygon[1] - 20"Arial""c"temp.angle);
  
changeImgVis(10057);
  
  if(
this.game_active){
    
scheduleEvent(0.05"MoveBall"temp.angle);
  }
}

function 
onClosePong(){

  
hideImgs(10001004);


If you scroll about halfway down, you'll get to the collision checks under the onMoveBall function, you'll see where I've highlighted my problem.
When the script is as it is in this post, the first collision check works fine but the second check does not, and RC gives no error messages about the script.
However, if you add a line before the second collision check such as this:

PHP Code:

player.chat "blah"

RC then gives an error message about the line below, causing the whole collision detection to stop working.
Thanks.

Hezzy002 01-22-2012 07:16 PM

Those checks are a little too complicated for a simple pong game, which is the first thing that stands out to me.

Pelikano 01-22-2012 08:01 PM

Well it's pretty obvious that if you place a player.chat = "bla"; before an else if that your code will break:

PHP Code:

if (bla) {

}
player.chat "hi";
else if (
bla2) {



This will obviously not work... so I don't think that it has anything to do with your syntax really lol

iBeatz 01-22-2012 08:20 PM

Quote:

Originally Posted by Pelikano (Post 1682411)
Well it's pretty obvious that if you place a player.chat = "bla"; before an else if that your code will break:

PHP Code:

if (bla) {

}
player.chat "hi";
else if (
bla2) {



This will obviously not work... so I don't think that it has anything to do with your syntax really lol

Ah yes, you're right.
I wasn't thinking straight when doing this it seems. Guess I was too frustrated trying to get my second collision check to work. Thanks.

Hezzy, can you suggest a simpler alternative to what I currently have?

cbk1994 01-22-2012 08:22 PM

Why are you storing angles as degrees and then repeatedly converting them to radians? Why not just store them as radians?

Hezzy002 01-22-2012 08:57 PM

Quote:

Originally Posted by iBeatz (Post 1682412)
Ah yes, you're right.
I wasn't thinking straight when doing this it seems. Guess I was too frustrated trying to get my second collision check to work. Thanks.

Hezzy, can you suggest a simpler alternative to what I currently have?

Well, it's just pong. You can just do an axis-aligned bounding box check, or rectangle intersection. You don't have to use any trig or angle work, just some basic math.

DustyPorViva 01-22-2012 09:27 PM

Actually from what I remember, using angles just made pong much more complicated to code. Use vectors instead.

fowlplay4 01-22-2012 09:27 PM

You can clean up your code quite a bit by:

1. Reducing the amount of math you do in an if statement.
2. temp.img = findimg(1004); then instead of using findimg(1004) just use your variable reference instead.
3. Same idea as 2 but you do the same calculation numerous times, do it once and store the value in a variable for re-use it instead.

salesman 01-22-2012 09:37 PM

Separate your presentation code from the game logic and you will simplify things immensely. You'll have code that's easier to understand, easier to change later, and is less prone to errors.

For example, something like:
PHP Code:

if (RIGHT_WALL_X ball.pos.ball.radius) {
  
// we have a collision on the right wall!!


is much easier to manage and understand than your code (which I'm only assuming is doing something similar to what's above):
PHP Code:

if(findImg(1004).polygon[temp.iy] - cos(degtorad(temp.angle)) * BALL_SPEED findImg(1000).polygon[1] || 
      
findImg(1004).polygon[temp.iy] - cos(degtorad(temp.angle)) * BALL_SPEED findImg(1000).polygon[7]){ 
      
temp.angle 180 temp.angle
    } 

In your game loop, you would have something like:
PHP Code:

function gameLoop() {
  
updateGame(); // updates the model (check for collisions, move ball, etc)
  
renderGame(); // draws the model in its current state

  // .. loop endlessly


Use simple units for the model (for example, a ball with a width of 1 unit instead of 16 pixels) and then when you are drawing the game, just convert the units to pixels (or tiles, or whatever). This would also allow you to change the way you render the game without having to mess with the game logic at all.

Also, I would use vectors for something like this, too.


All times are GMT +2. The time now is 10:01 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.