alecz127
817 posts
|
So I'm making a platform game and using an advanced method of collision detection that I'm still learning how to use properly.
The first class is the most important one in figuring out whats wrong, as it deals with all the collisions of the main character. The other two classes have code that is related to this one. Such as setting it up.
The main issue that I am having is that my main character has a width and height the same as the tiles. 50 by 50px.
So when I change playerWidth and playerHeight in collision.as to 25 by 25px respectively, the player seems to teleport downwards when he has an upward collision. But If I alter the variable playerHeight and increase the value from 25 to 30, the collision detection works fine. The player jumps up, hits the top tile, collision which stops the player from moving further upwards, the player falls back downwards to the tile below him due to gravity.
Why does changing the height value matter?
I've implimented several trace statements to follow the positioning, and other collision.as related values of the player to see what was causing this "teleporting effect"
I'm still working on it, and still stuck as to how I can alter this to work properly.
//Collision Class
package{
public class collisions {
private var tileWidth:int; // game slicing tile's width
private var tileHeight:int; // game slicing tile's height
private var playerWidth:int = 25 // half of real width
private var playerHeight:int = 25 // half of real height
private var map; // map data container
private var forecast_x:int; // where the player will be at the end of the frame
private var forecast_y:int;
public var can_jump:Boolean; // if player can jump
private var player; // to store the player object in
public function setup(setWidth,setHeight,setMap,setPlayer) {
tileWidth = setWidth;
tileHeight = setHeight
map = setMap;
player = setPlayer;
}
//*********************************************************
public function find_corners(point_x,point_y) {
// Looks in wich tiles(not pixels) these four point are.
// Will be used to get the position of the corners and to get the end position of the player.
player.downy = Math.round((point_y + playerHeight - tileHeight/2) / tileHeight);
player.upy = Math.round((point_y - playerHeight - tileHeight/2) / tileHeight);
trace("POINT_Y: " + point_y);
trace("PLAYER.UPY: " + player.upy);
player.rightx = Math.round((point_x + playerWidth - tileWidth/2) / tileWidth)
player.leftx = Math.round((point_x - playerWidth - tileWidth/2) / tileWidth);
// Gets the sort tile the position of the corners has.
// One means there can be collision, zero is air.
player.downright = map[player.downy][player.rightx];
player.upright = map[player.upy][player.rightx];
if (map[player.downy-1][player.rightx] == 1) player.downright = 1 ; // Because player is higher than tile we also have to check at middle point
if (map[player.upy+1][player.rightx] == 1) player.upright = 1 ;
player.downleft = map[player.downy][player.leftx];
player.upleft = map[player.upy][player.leftx];
if (map[player.downy-1][player.leftx] == 1) player.downleft = 1 ; // Because player is higher than tile we also have to check at middle point
if (map[player.upy+1][player.leftx] == 1) player.upleft = 1 ;
}
//*********************************************************
public function check_ground() {
player.downy = Math.round((player.y + (playerHeight+1) - tileHeight/2) / tileHeight);
player.rightx = Math.round((player.x + playerWidth - tileWidth/2) / tileWidth)
player.leftx = Math.round((player.x - playerWidth - tileWidth/2) / tileWidth);
// Makes three points in tile-coordinates
player.downleft = map[player.downy][player.leftx];
player.downright = map[player.downy][player.rightx];
// Checks the sort
if(player.downleft == 1 || player.downright ==1){ // if there is any collision by the player's feet
can_jump = true; // than can jump
}
else{
can_jump = false; // else not
}
}
//*********************************************************
public function solve(forecastx, forecasty) {
// It's four times almost the same. It checks for collision between the spots,
// the four spots if there only were x_speeds, the four spots if there only was y_speed,
// the four spots if there were both y- and x_speed.
// That are 3*4 = 12 spots.
//
// var explanation:
//
// downC -> is collision under the spot
// upC -> is collision above the spot
// rightC -> is collision right from the spot
// leftC -> is collision left from the spot
forecast_x = forecastx;
forecast_y = forecasty;
find_corners(forecast_x,forecast_y);
if(player.downleft == 1) {
find_corners(player.x,forecast_y);
if(player.downleft == 1) {
player.downC = true;
}
else{
player.downC = false;
}
find_corners(forecast_x,player.y);
if(player.downleft == 1) {
player.leftC = true;
}
else{
player.leftC = false;
}
if(player.leftC && player.downC) {
forecast_x = (player.leftx+1) * tileWidth + playerWidth;
forecast_y = (player.downy+1) * tileHeight - (playerHeight+1);
player.y_speed = 0;
}
else if(player.leftC) {
forecast_x = (player.leftx+1) * tileWidth + playerWidth;
}
else if(player.downC) {
forecast_y = (player.downy+1) * tileHeight - (playerHeight+1);
player.y_speed = 0;
}
}
find_corners(forecast_x,forecast_y);
if(player.downright == 1) {
find_corners(player.x,forecast_y);
if(player.downright == 1){
player.downC = true;
}
else{
player.downC = false;
}
find_corners(forecast_x,player.y);
if(player.downright == 1){
player.rightC = true;
}
else{
player.rightC = false;
}
if(player.rightC && player.downC) {
forecast_x = player.rightx * tileWidth - (playerWidth+1);
forecast_y = (player.downy+1) * tileHeight - (playerHeight+1);
player.y_speed = 0;
}
else if(player.rightC) {
forecast_x = player.rightx * tileWidth - (playerWidth+1);
}
else if(player.downC) {
forecast_y = (player.downy+1) * tileHeight - (playerHeight+1);
player.y_speed = 0;
}
}
find_corners(forecast_x,forecast_y);
if(player.upleft == 1) {
find_corners(player.x,forecast_y);
if(player.upleft == 1) {
player.upC = true;
}
else{
player.upC = false;
}
find_corners(forecast_x,player.y);
if(player.upleft == 1) {
player.leftC = true;
}
else{
player.leftC = false;
}
if(player.leftC && player.upC) {
forecast_x = (player.leftx+1) * tileWidth + playerWidth;
forecast_y = (player.upy) * tileHeight + playerHeight;
player.y_speed = 0;
}
else if(player.leftC) {
forecast_x = (player.leftx+1) * tileWidth + playerWidth;
}
else if(player.upC) {
forecast_y = (player.upy) * tileHeight + playerHeight;
player.y_speed = 0;
}
}
find_corners(forecast_x,forecast_y);
if(player.upright == 1) {
find_corners(player.x,forecast_y);
if(player.upright == 1) {
player.upC = true;
}
else{
player.upC = false;
}
find_corners(forecast_x,player.y);
if(player.upright == 1){
player.leftC = true;
}
else{
player.leftC = false;
}
if(player.leftC && player.upC) {
forecast_x = player.rightx * tileWidth - (playerWidth+1);
forecast_y = (player.upy) * tileHeight + playerHeight;
player.y_speed = 0;
}
else if(player.leftC) {
forecast_x = player.rightx * tileWidth - (playerWidth+1);
}
else if(player.upC) {
forecast_y = (player.upy) * tileHeight + playerHeight;
player.y_speed = 0;
}
}
player.x = forecast_x; // place the player
player.y = forecast_y;
trace("FORECAST_Y: " + forecast_y);
check_ground() // runs the function to check for ground
}
//*********************************************************
}
}
//Main Class
package {
import flash.display.*;
import flash.events.*;
import flash.ui.*;
import flash.utils.Timer;
import flashx.textLayout.elements.InlineGraphicElement;
public class SkyEngine extends MovieClip {
private var player:sky = new sky;
private var mapHolder:MovieClip = new MovieClip();
public static var ground_a:Array = new Array();
public var tile_width = 50;
public var tile_height = 50;
private var forecast_x:int;
private var forecast_y:int;
//PLAYER MOVEMENTS
private const gravity = 2;
private const maxSpd:int = 16;
private const walkSpd:int = 8;
private const jumpSpd:int = 20;
private var left:Boolean;
private var right:Boolean;
private var up:Boolean;
public var map:Array = new Array();
public var map_data:mapData = new mapData;
public var tiles:Array = new Array();
public var player_collisions:collisions = new collisions;
public var jump_trigger = true;
private const startX = 250;
private const startY = 200;
private var flipped:Boolean = false;
private var jumpTrigger:Boolean = false;
private var walkTrigger:Boolean = false;
private var skyRunning:Boolean = false;
public function SkyEngine() {
createMap();
createPlayer();
stage.addChild(mapHolder);
stage.addEventListener(KeyboardEvent.KEY_DOWN, kDL);
stage.addEventListener(KeyboardEvent.KEY_UP, kUL);
stage.addEventListener(Event.ENTER_FRAME, loop);
player.width = 50;
player.height = 50;
player_collisions.setup(tile_width,tile_height,map,player);
}
public function createMap(){
map_data.setup();
map = map_data.map_array;
mapHolder.x = 0;
mapHolder.y = 0;
for(var t = 0; t < map.length; t++){
for(var u = 0; u < map[t].length; u++){
if(map[t][u] == 1){
var tile:ground = new ground;
mapHolder.addChild(tile);
tile.gotoAndStop(1);
tile.x = u * 50;
tile.y = t * 50;
ground_a.push(tile);
}
}
}
//map
}
private function createPlayer(){
addChild(player);
player.x = startX;
player.y = startY;
player.xSpd = 0;
player.ySpd = 0;
jumpTrigger = true;
}
public function kDL(e:KeyboardEvent):void{
if(e.keyCode == 37 || e.keyCode == 65){
left = true;
if(player.currentFrame < 90||player.currentFrame > 105){
player.gotoAndPlay("RUN");
}
player.rotationY = 180;
}
if(e.keyCode == 38 || e.keyCode == 87){
up = true;
jump_trigger = true;
}
if(e.keyCode == 39 || e.keyCode == 68){
right = true;
if(player.currentFrame < 90||player.currentFrame > 105){
player.gotoAndPlay("RUN");
}
player.rotationY = 0;
}
}
public function kUL(e:KeyboardEvent):void{
if(e.keyCode == 37 || e.keyCode == 65){
left = false;
}
if(e.keyCode == 38 || e.keyCode == 87){
up = false;
}
if(e.keyCode == 39 || e.keyCode == 68){
right = false;
}
player.gotoAndPlay(1);
}
public function loop(e:Event){
updatePlayer();
}
private function updatePlayer(){
player.ySpd += gravity;
if (left == true) {
player.xSpd = -walkSpd;
}
if (right == true) {
player.xSpd = walkSpd;
}
if (up && player_collisions.can_jump) {
player.ySpd = -jumpSpd;
}
if (player.ySpd > maxSpd) {
player.ySpd = maxSpd;
}
forecast_y = player.y + player.ySpd;
forecast_x = player.x + player.xSpd;
player_collisions.solve(forecast_x, forecast_y);
player.xSpd = 0;
if(player_collisions.can_jump){
jumpTrigger = true;
}
}
}
}
// Map Data Class
package{
public class mapData {
public var map_array:Array = new Array();
public function setup(){
//trace("uberboobage");
map_array = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]
}
}
}
|