5 Replies - 1964 Views - Last Post: 02 September 2010 - 06:23 AM Rate Topic: -----

#1 11ty3  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 30-August 10

Sonic the hedgehog?

Posted 31 August 2010 - 06:39 AM

Well, I've been programming a while, but the only thing I still need to make on my checklist of 2D games is a sonic the hedgehog style game, loops and all. However, I can't make my game do any more than slopes, I tried, thought, tried some more, basically worked my arse off and can't figure out where my problem is with this. I used 2 Images to define my level, 1 is in black and white, Black = air/blank(where you can go), white = ground/platforms(where you can't go). I have been trying to do this with Hotpoints, 4 of them to be exact. 1 each for head, foot, left and right side. I will post my code, but I get some weird glitches, He kinda runs, but randomly VERY often, my little character freaks out. I will post my code PLZ HELP. Also I cannot get him to actually have a realistic rotation while resting on a slope. If necessary I can post the other files in my game, theres about 7 of them. Here is the hole Character class(the super class for anything resting on the ground) and the Movement class which I made for 360 Degree movements PLEASE HELP This is the driving class in my project, all the others seem to work.
I should probably define the glitch more. The glitch occurs multiple times, A going up a slope, G going right and C randomly. The glitch either throws the player away from the wall or floor, freezes the game with the character inside the wall somewhere,freezes the characters movement till key is released, or randomly throws the character.
import java.awt.geom.AffineTransform;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import javax.imageio.*;
public class Character implements KeyListener {
    public static final double GRAVITY = 0.025;
    public static final boolean LEFT = false, RIGHT = true;
    double x, y;
    double vSpeed, hSpeed;
    double rotation = 0;
    boolean direction = true;
    byte jumps;
    Point last;
    Map map;
    boolean done, moving;
    Sprite image;
    Sprite stand, run, jump, fall, idle;
    protected float image_speed=3F, image_countdown=0;
            //note: character is 17 pixels wide and 31 pixels tall
    public Character(int x, int y) {
        this.x = x;
        this.y = y;
        this.direction = true;
        idle =  new Sprite("Images/Player/idle.png", 4, this);
        stand = new Sprite("Images/Player/stand.png", 1, this);
        run =   new Sprite("Images/Player/run.png", 4, this);
        jump =  new Sprite("Images/Player/jump.png", 2, this);
        fall =  new Sprite("Images/Player/fall.png", 2, this);
        image = stand;
    }
    public Character() {
        this.x = 0;
        this.y = 0;
        idle =  new Sprite("Images/Player/idle.png", 4, this);
        stand = new Sprite("Images/Player/stand.png", 1, this);
        run =   new Sprite("Images/Player/run.png", 4, this);
        jump =  new Sprite("Images/Player/jump.png", 2, this);
        fall =  new Sprite("Images/Player/fall.png", 2, this);
        image = stand;
    }
    public void animationend(Sprite spr) {
        if(spr == stand) {
            setSprite(idle);
        }
    }
    public void setSprite(Sprite spr) {
        if(image == spr) {
        } else {
            image = spr;
            image_countdown=0;
        }
        if(image == idle) {
            image_speed = 25F;
        } else if(image == stand) {
            image_speed = 300F;
        } else if(image == run) {
            image_speed = 6.5F - (float)(Math.abs(hSpeed) * 2);
        } else {
            image_speed = 7.5F;
        }
    }
    public Dimension size() {
        return new Dimension(16, 30);
    }
    public boolean aerial() {
        Point l = feetHotPoint();
        move(l, downRotation(), 1);
        if( !solid( l )) {
            rotation = 0;
            return true;
        } else {
            return false;
        }
    }
    public boolean colliding(Character other) {
        int leftSide = (int)x - (size().width / 2);
        int rightSide = (int)x + (size().width / 2);
        int top = (int)y - size().height;
        int bottom = (int)y;
        
        int eLeftSide = (int)other.x - (other.size().width / 2);
        int eRightSide = (int)other.x + (other.size().width / 2);
        int eTop = (int)other.y - other.size().height;
        int eBottom = (int)other.y;
        if(eLeftSide < rightSide)
            if(eRightSide > leftSide)
                if(eTop < bottom)
                    if(eBottom > top)
                        return true;
        return false;
    }
    public void collision(Character other) {
        //does nothing as default
    }
    public Point feetHotPoint() {
        return new Point((int)x, (int)y);
    }
    public void move(Point pt, double direction, double speed) {
        Movement m = new Movement();
        m.move( direction, speed );
        pt.x += m.hSpeed;
        pt.y += m.vSpeed;
    }
    public Point headHotPoint() {
        Movement m = new Movement();
        Point p = feetHotPoint();
        move(p, upRotation(), 31);
        return p;
    }
    public Point leftHotPoint() {
        Point p = feetHotPoint();
        move(p, upRotation(), 16);
        move(p, leftRotation(), 7);
        return p;
    }
    public Point rightHotPoint() {
        Point p = feetHotPoint();
        move(p, upRotation(), 16);
        move(p, rightRotation(), 7);
        return p;
    }
    public double leftRotation() {
        return rotation + 180;
    }
    public double rightRotation() {
        return rotation;
    }
    public double upRotation() {
        return rotation - 90;
    }
    public double downRotation() {
        return rotation + 90;
    }
    public void keyReleased(KeyEvent ke) {}
    public void keyPressed(KeyEvent ke) {}
    public void keyTyped(KeyEvent ke) { }
    public void step() {
        vSpeed += GRAVITY;
        if(aerial()) {
            last = new Point((int)x, (int)y);
            y += vSpeed;
            x += hSpeed;
        } else {
            y += vSpeed;
            x += hSpeed;
            last = new Point((int)x, (int)y);
            if(direction==RIGHT) {
                move(last, rightRotation(), 1);
            } else if(direction==RIGHT) {
                move(last, leftRotation(), 1);
            }
        }
        if(moving) {
            move();
        }
        if(!aerial()) {
            if(hSpeed!=0) {
                setSprite(run);
            }
            if(hSpeed==0) {
                if(image != idle) {
                    setSprite(stand);
                }
            }
        } else {
            if(vSpeed<=0) {
                setSprite(jump);
            } else {
                setSprite(fall);
            }
        }
            //feet hotpoint
        if( solid( feetHotPoint() ) ) {
            vSpeed = 0;
            jumps = 1;
            if(!moving) {
                hSpeed = 0;
            }
            while( solid( feetHotPoint() ) ) {
                Point p = feetHotPoint();
                move(p, upRotation(), 1);
                x = p.x;
                y = p.y;
            }
        }
            //head hotpoint
        if( solid( headHotPoint() ) ) {
            Movement m = new Movement();
            m.move(rotation + 90, 1.25);
            hSpeed = m.hSpeed;
            vSpeed = m.vSpeed;
            if( solid( headHotPoint() ) ) {
                while( solid( headHotPoint() ) ) {
                    Point p = feetHotPoint();
                    move(p, downRotation(), 1);
                    x = p.x;
                    y = p.y;
                }
            }
        }
            //left hotpoint
        if( solid( leftHotPoint() ) ) {
            if(aerial()) {
                hSpeed = 0;
            } else {
                hSpeed = 0;
            }
            if( solid( leftHotPoint() ) ) {
                while( solid( leftHotPoint() ) ) {
                    Point p = feetHotPoint();
                    move(p, rightRotation(), 1);
                    x = p.x;
                    y = p.y;
                }
            }
        }
            //right hotpoint
        if( solid( rightHotPoint() ) ) {
            if(aerial()) {
                hSpeed = 0;
            } else {
                hSpeed = 0;
            }
            if( solid( rightHotPoint() ) ) {
                while( solid( rightHotPoint() ) ) {
                    Point p = feetHotPoint();
                    move(p, leftRotation(), 1);
                    x = p.x;
                    y = p.y;
                }
            }
        }
        image_countdown+=1;
        if(image_countdown>image_speed) {
            addIndex();
            image_countdown=0;
        }
        if(moving) {
            Movement m = new Movement();
            m.vSpeed = last.y - y;
            m.hSpeed = last.x - x;
            rotation = m.direction();
        }
    }
    public void move() {
        double ySpeed = vSpeed;
        if(direction == LEFT) {
            Movement m = new Movement();
            m.move(leftRotation(), 1.25);
            vSpeed = m.vSpeed;
            hSpeed = m.hSpeed;
        } else if(direction == RIGHT) {
            Movement m = new Movement();
            m.move(rightRotation(), 1.25);
            vSpeed = m.vSpeed;
            hSpeed = m.hSpeed;
        }
        if(!aerial()) {
            y += 1;
        } else {
            vSpeed += ySpeed;
        }
        Movement m = new Movement();
        m.vSpeed = last.y - y;
        m.hSpeed = last.x - x;
        rotation = m.direction();
    }
    public void jump() {
        if(jumps == 0) {
            return;
        } else {
            jumps -= 1;
            Movement m = new Movement();
            m.move(upRotation(), 3.25);
            vSpeed = m.vSpeed;
            hSpeed = m.hSpeed;
        }
    }
    public void draw(Graphics gx) {
        if(aerial()) {
            //rotation = 0;
        }
        Graphics2D g = (Graphics2D)gx;
        AffineTransform a = g.getTransform();
        g.rotate(Math.toRadians(rotation),x,y);
        BufferedImage im = image.getCurrent();
        if(direction==RIGHT) {
            g.drawImage(im, (int)x-(im.getWidth()/2), (int)y-(im.getHeight())+1, null);
        } else {
            g.drawImage (im, (int)x-(im.getWidth()/2)+im.getWidth(), (int)y-(im.getHeight()), 0, 
                 (int)y-(im.getHeight())+im.getHeight()+1, 0, -1, (int)x-(im.getWidth()/2)+im.getWidth(),
                 im.getHeight(), null);
        }
        g.setTransform(a);
        g.setColor(Color.red);
        g.drawRect( leftHotPoint().x, leftHotPoint().y, 0, 0 );
        g.drawRect( rightHotPoint().x, rightHotPoint().y, 0, 0 );
        g.drawRect( headHotPoint().x, headHotPoint().y, 0, 0 );
        g.drawRect( feetHotPoint().x, feetHotPoint().y, 0, 0 );
    }
    public boolean solid(double x, double y) {
        try {
            int pixel = map.collision.getRGB((int)x, (int)y);
            if(pixel == Color.black.getRGB()) {
                return false;
            } else {return true;}
        } catch(Throwable t) {return true;}
    }
    public boolean solid(Point pt) {
        return solid(pt.x, pt.y);
    }
    public BufferedImage getView(BufferedImage B)/> {
        int x, y, width, height, fx, fy;
        fx = (int)(this.x);
        fy = (int)(this.y - 20);
        x = fx - 200 + 300;
        y = fy - 150 + 200;
        width = 400;
        height = 300;
        return b.getSubimage(x, y, width, height);
    }
    public void addIndex() {
        image.index+=1;
    }
}



class Movement {
    public double hSpeed, vSpeed;
    public void move( double degree, double speed) {
        while(degree<0) {
            degree+=360;
        }
        while(degree>360) {
            degree-=360;
        }
        double direction = Math.toRadians(degree);
        if(direction >= 0 && direction <= 90) {
            hSpeed = Math.cos(direction) * speed;
            vSpeed = Math.sin(direction) * speed;
        }  else if(direction >= 91 && direction <= 180) {
            hSpeed = -(Math.cos(90 - direction) * speed);
            vSpeed = Math.sin(90 - direction) * speed;
        } else if(direction >= 181 && direction <= 270) {
            hSpeed = -(Math.cos(180 - direction) * speed);
            vSpeed = -(Math.sin(180 - direction) * speed);
        } else if(direction >= 271 && direction <= 360) {
            hSpeed = Math.cos(270 - direction) * speed;
            vSpeed = -(Math.sin(270 - direction) * speed);
        }
    }
    public double direction() {
        if(vSpeed == 0 & hSpeed != 0) {
            if(hSpeed>0) {
                return 0;
            } else {
                return 180;
            }
        } else if(hSpeed == 0 & vSpeed != 0) {
            if(vSpeed>0) {
                return 270;
            } else {
                return 90;
            }
        }
        double s=(vSpeed/hSpeed);
        double result=(Math.atan(s));
        double finalR= Math.toDegrees(result);
        if(vSpeed==0 | hSpeed==0)
            finalR+=180;
        if(hSpeed!=0) {
            return finalR;
        } else if(vSpeed!=0) {
            return finalR;
        } else {
            return 0;
        }
    }
    public double speed() {
        double direction = direction();
        if(direction >= 0 && direction <= 90) {
            return Math.cos(direction) / hSpeed;
        }  else if(direction >= 91 && direction <= 180) {
            return -(Math.cos(90 - direction)) / hSpeed;
        } else if(direction >= 181 && direction <= 270) {
            return -(Math.cos(90 - direction)) / hSpeed;
        } else if(direction >= 271 && direction <= 360) {
            return Math.cos(direction) / hSpeed;
        } else {
            return 0;
        }
    }
}



Is This A Good Question/Topic? 0
  • +

Replies To: Sonic the hedgehog?

#2 11ty3  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 30-August 10

Re: Sonic the hedgehog?

Posted 31 August 2010 - 01:57 PM

Can ANYONE help me?
frikkin glitch I hate you.
Was This Post Helpful? 0
  • +
  • -

#3 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8324
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Sonic the hedgehog?

Posted 31 August 2010 - 04:33 PM

Where did you get your Graphics object that you pass to your draw() method ?
Was This Post Helpful? 0
  • +
  • -

#4 11ty3  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 30-August 10

Re: Sonic the hedgehog?

Posted 01 September 2010 - 03:04 PM

View Postpbl, on 31 August 2010 - 02:33 PM, said:

Where did you get your Graphics object that you pass to your draw() method ?

It's passed in through a loop in an applet that is sent to the Level object which draw the background and then passes it in turn into the draw method of each added character. Each frame is about 17 milliseconds apart btw.
Was This Post Helpful? 0
  • +
  • -

#5 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8324
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: Sonic the hedgehog?

Posted 01 September 2010 - 09:26 PM

View Post11ty3, on 01 September 2010 - 04:04 PM, said:

View Postpbl, on 31 August 2010 - 02:33 PM, said:

Where did you get your Graphics object that you pass to your draw() method ?

It's passed in through a loop in an applet that is sent to the Level object which draw the background and then passes it in turn into the draw method of each added character. Each frame is about 17 milliseconds apart btw.

And how does the Applet get it ?
How does your Applet loops on it ?
We are not out of the woods if I have to beg for every pertinent info
The human eye can see changes every 16ms, would be useless to refresh faster than that but 17ms should be OK
Was This Post Helpful? 1
  • +
  • -

#6 11ty3  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 30-August 10

Re: Sonic the hedgehog?

Posted 02 September 2010 - 06:23 AM

import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import javax.imageio.*;
import java.io.File;
public class Main extends JApplet implements Runnable{
    public static final Point offset = new Point(300, 200);
    private static final int FPS = 11;
    Map map = new Level2();
    BufferedImage buffer = new BufferedImage(1400,1000,BufferedImage.BITMASK);
    Thread runner;
    public static void main(String arguments[]) {
        JFrame window = new JFrame("Dashlash");
        window.setLayout(new BorderLayout());
        window.add(new Main(), BorderLayout.CENTER);
        window.pack();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setLocationRelativeTo(null);
        window.setResizable(false);
        window.setVisible(true);
    }
    public static BufferedImage loadImage(String path) {
        try {
            File file = new File(path);
            BufferedImage image = ImageIO.read(file);
            return image;
        } catch(Throwable t) { return null; }
    }
    public Main() {
        super();
        setSize(800,600);
        setPreferredSize(new Dimension(790, 590));
        loadMap(map);
        runner = new Thread(this);
        runner.start();
    }
    public void loadMap(Map map) {
        this.map = map;
        Map.main = this;
        for(Character c : map.objects) {
            addKeyListener(c);
            c.map = map;
            buffer = new BufferedImage(
                map.view.getWidth() + 600,map.view.getHeight() + 400,
                BufferedImage.BITMASK);
        }
    }
    public void paint(Graphics g) {
        update(g);
    }
    public void run() {
        long tm = System.currentTimeMillis();
        while(true){
            map.step();
            repaint();
            try {
                tm += FPS;
                Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));
            }
            catch(InterruptedException e)
            {
                System.out.println(e);
            }
        }
    }
    public void update(Graphics g) {
        Graphics g2 = buffer.createGraphics();
        g2.setColor(map.background());
        g2.fillRect(0,0,buffer.getWidth(),buffer.getHeight());
        g2.translate(offset.x, offset.y);
        map.draw(g2);
        if(map.focus == null) {
            g.drawImage(buffer, 0, 0, this);
        } else {
            BufferedImage view;
            view = map.focus.getView(buffer);
            g.drawImage(view, 0, 0, 800, 600, this);
        }
    }
}


Here's the code, as you can see, the graphics are gotten from a BufferedImage called buffer, which is passed to the map, then each Character object. If it'll help here's my Map class as well.
import java.awt.image.*;
import java.awt.*;
import java.util.*;
public class Map {
    static Main main;
    public BufferedImage view, collision;
    public Vector<Character> objects = new Vector<Character>();
    public Vector<Character> remove  = new Vector<Character>();
    Character focus;
    public Map() {
        initMap();
    }
    public void step() {
        for(Character c : objects) {
            if(c.done) {
                remove.add(c);
                continue;
            }
        }
        for(Character c : remove) {
            objects.remove(c);
        }
        remove = new Vector<Character>();
        for(Character c : objects) {
            c.step();
            for(Character other : objects) {
                if(c.colliding(other) & other != c) {
                    c.collision(other);
                }
            }
        }
    }
    public Map nextMap() {
        return this;
    }
    public void endLevel() {
        main.loadMap(nextMap());
    }
    public void initMap() {
        focus = new Player(startLocation().x, startLocation().y);
        objects.add(focus);
        //does nothing in this version
    }
    public void draw(Graphics g) {
        g.drawImage(view, 0, 0, null);
        for(Character c : objects) {
            c.draw(g);
        }
    }
    public Color background() {
        return Color.black;
    }
    public Point startLocation() {
        return new Point(50, 50);
    }
}


and here is how Level1 overrides this class
import java.awt.*;
public class Level1 extends Map {
    public Level1() {
        view      = Main.loadImage("Images/View1.png");
        collision = Main.loadImage("Images/Map1.png");
    }
    public Color background() {
        return new Color(34, 177, 76);
    }
    public void initMap() {
        super.initMap();
        objects.add(new Enemy(522, 311));
        objects.add(new Door(395, 386));
    }
    public Map nextMap() {
        return new Level2();
    }
    public Point startLocation() {
        return new Point(144, 366);
    }
}


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1