Kollisionsabfrage implementieren

Keyone94

Mitglied
hab mal ein paar Struktur Tipps für zukünftige Projekte:
1.) Klassen wie Player, MapObject und ähnliches sind im normalfall reine Informations Klassen, dh. sie haben hauptsächlich Variablen mit gettern und settern und fast nie konkrete Methoden (wie Kollisionkontrolle oder ähnliches)

2.) man schreibt statdessen eine Physik (oder eine verwaltung der Objekte oder ähnliches, welche einerseits die Map und andererer Seits alle Objekte die auf der Map laufen besitzt)
2.5.) die Sachen wie keyPressed / keyReleased sollten auch nicht in Player stehen, sondern entweder in der Klasse darüber oder in der Physik oder so

3.) wenn der Spieler als Mittelpunkt des Spiels gesehen wird (wenn man also nur einen Spieler hat, der besonders ist) wird dieser meistens als Sonderwurst behandelt (also es gibt z.B. eine Liste mit mapObjects und eine Instanz von Spieler)


zu deinem Problem mit der bewegten Map:
du willst die Map abhängig von der Spieler Position zeichen, dh.
1.) der Spieler wird immer genau in der Mitte des Bildes gezeichnet
2.) die Map wird abhängig von x und y gezeichnet
( 3.) falls du willst kannst du später noch einbauen, dass wenn man sich dem Rand nähert, die Position des Spielers verändert wird anstelle der Map (man also am Rand der Wand entgegen läuft) )

Java:
//draw Player
        g.setColor(Color.RED);
        g.fillRect( 5*tilesize,  5*tilesize, width, height);

//draw map
        for (int row = 0; row < map.length; row++) {
            for (int col = 0; col < map[row].length; col++) {
                if(map[row][col] == 1) {
                    g.setColor(Color.BLACK);
                }
                if(map[row][col] == 0) {
                    g.setColor(Color.WHITE);
                }
                g.fillRect( col  * tileSize - x,  row  * tileSize - y, tileSize, tileSize);
            }
        }

[EDIT]Ich würde die Position der Map nicht als eigene Variable machen, denn:
je mehr Variablen man hat, die aufeinander abgestimmt sein müssen, um so Fehler anfälliger wird das ganze

Mal abgesehen davon gibt es so dermaßen unvollständige und fehlerbehaftete, tutorials im Netz das es mir mittlerweile kalt den Rücken runter läuft..... hoffe mein Buch ist bald da
also ich hab Programmierung auch mit diesen Tutorials gelernt (nie in ein Buch geschaut und bis auf mein Info Studium inzwischen (wo man leider nichts wirklich lernt)) komplett mit dem Internet gelernt
[/EDIT]
 
Zuletzt bearbeitet:

kaoZ

Top Contributor
hab mal ein paar Struktur Tipps für zukünftige Projekte:

Deine dort aufgelisteten Punkte sind Plausibel, danach richte ich mich in meinen sonstigen Projekte sowieso, der hier gepostete Code , ist einem Online Tutorial nachempfunden, und nicht auf meinem Mist gewachsen, deswegen unter anderem auch meine Aussage das viele Online Tutorials hinsichtlich der Spieleprogrammierung nicht nur unübersichtlich sind,
sondern auch teilweise recht komplex, und oder sogar Fehlerhaft.

Da ich mich wie schon erwähnt vorher nicht mit Spielprogrammierung befasst habe , würde ich halt ganz gerne eine eigene Engine schrieben um das ganze auch nachvollziehen zu können, wie movement, scrolling, kollisionsabfragen usw. ineinandergreifen.
(ich vermute mal das meinstest du mit Physik)

Sicher könnte ich auch einfach irgendeine fertige Engine nutzen wie Libgdx, Slick2D, und wie sie nicht alle heißen, das ist aber nicht mein Ziel!


mein Problem ist letztendlich auch nicht die Gliederung, der Aufbau oder die Kollisionsabfrage, sondern lediglich das Verständnis dafür wie sich die Positionen von map und Player zueinander verhalten , deshalb hatte ich ein schnell programmiertes Beispiel gepostet, wo alle relevanten dinge in einer Klasse zusammengefasst sind, und ja dies ist nicht OO, sondern dient lediglich dazu , das ich leichter nachvollziehen konnte wie sich die einzelnen koordinaten zueinander verhalten müssen, bzw. an welchen stellen was gezeichnet wird.

Zu deiner Aussage das ein Player sich nicht um das Movement etc. kümmern sollte, gebe ich dir natürlich vollkommen recht, es sollten lediglich setter / getter angeboten werden, wie sich der Spieler / das Objekt dann bewegt sollte dem Objekt selbst dann egal sein .

Das hier würde den Player in die Mitte zeichenen :

Java:
//draw Player
		g.setColor(Color.RED);
		g.fillRect(WIDTH / 2 - width / 2, HEIGHT / 2 - height / 2, width, height);

in verbindung mit der Map:
Java:
		//draw map
		for (int row = 0; row < map.length; row++) {
			for (int col = 0; col < map[row].length; col++) {
				if(map[row][col] == 1) {
					g.setColor(Color.BLACK);
				}
				if(map[row][col] == 0) {
					g.setColor(Color.WHITE);
				}
				g.fillRect(col * tileSize - x, row * tileSize - y, tileSize, tileSize);
			}
		}

würde auch das scrollen funktionieren , allerdings müsste ich mich dann noch um das zeichnen kümmern wenn der Player sich nun richtung Rand bewegt, da wird die map momentan nämlich nicht gezeichnet.


Zumal dann auch die koordinaten nichtmehr passen , die ich an dieser Stelle ausgeben lasse, und somit auch die Zeile und spalte an der sich der Player ja auf der map befindet , was wiederrum für die kollisionsabfrage notwendig ist .

Java:
		//draw info
		g.drawString("Cord. : " + x + "|" + y, x, y + height * 2);
		g.drawString("Pos. : " + y / tileSize + "|" + x / tileSize, x, y + height * 2 + 20);


jetzt nehmen wir doch aber mal an ich habe eine map mit den ausmaßen 1200x1200
und einen aktiven Sichtbereich von 640x480, also die map ist größer als der Sichtbereich, und ich würde nun den Player und schlussfolgernd dessen die map aktiv über dessen x und y koordinaten bewegen, dann müsste ich ja da der Spieler ab einer x position von > 640 sonst aus dem Sichtbereich laufen würde , so zeichnen das er eben innerhalb des Sichtbaren bereiches bleibt, also muss ich map und player auf den sichtbaren bereich translaten , und ich denke das wird auch in dem Tutorial gemacht, nur das er nicht die translate() methode verwendet sondern anhand von player und map koordinaten diese so zeichnet das der player immer im sichtbaren bereich bleibt, und da haperts noch ziemlich ^^

ich kann den Player also nicht einfach an x und y koordinate zeichnen da diese ja irgendwann nicht mehr im Sichtbereich liegen, zusätzlich muss ich die map so zeichnen das ich die aktuelle player position mit einbeziehe, und da scheitert es nich irgendwie grade.....
 
Zuletzt bearbeitet:

kaoZ

Top Contributor
Ich habe nun mal die Map vergrößert, hier wird der Player fix in die Mitte des Sichtbaren bereiches gezeichnet und die map anhand der x und y koordinaten bewegt,

(Das ist, soweit ich es nachvollziehen kann,nicht mein Ziel)
falls du sowas meinstest

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;



@SuppressWarnings("serial")
public class Foo extends JPanel implements Runnable, KeyListener{

	
	final static int WIDTH	= 320;
	final static int HEIGHT = 240;
	
	//player
	int x;
	int y;
	int xmove;
	int ymove;
	int width;
	int height;
	
	//map
	int tileSize;
	int xmap;
	int ymap;
	
	int[][] map = 
		{
			{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
			{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
			{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
			{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
			{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
			{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
			{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
			{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
			{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
			{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
			{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
			{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
			{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
			{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
			{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
			{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
			{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
			{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0},
			{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
			{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}
		};
	
	//movement
	boolean left;
	boolean right;
	boolean up;
	boolean down;
	
	//loop
	Thread loop;
	boolean running;
	
	public Foo(){
		
		width = 20;
		height = 20;
		
		tileSize = 32;
		
		setPosition(20, 20);
		setMapPosition(0, 0);
		
		setPreferredSize(new Dimension(WIDTH, HEIGHT));
		setFocusable(true);
		requestFocus();
		
	}
	
	private void setPosition(int x, int y){
		this.x = x;
		this.y = y;
	}
	
	private void setMapPosition(int xmap, int ymap){
		this.xmap = xmap;
		this.ymap = ymap;
	}
	
	@Override
	public void keyTyped(KeyEvent e){}

	@Override
	public void keyPressed(KeyEvent e){
		if(e.getKeyCode() == KeyEvent.VK_LEFT) {
			left = true;
		}
		if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
			right = true;
		}
		if(e.getKeyCode() == KeyEvent.VK_UP) {
			up = true;
		}
		if(e.getKeyCode() == KeyEvent.VK_DOWN) {
			down = true;
		}
	}
	
	@Override
	public void keyReleased(KeyEvent e){
		if(e.getKeyCode() == KeyEvent.VK_LEFT) {
			left = false;
		}
		if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
			right = false;
		}
		if(e.getKeyCode() == KeyEvent.VK_UP) {
			up = false;
		}
		if(e.getKeyCode() == KeyEvent.VK_DOWN) {
			down = false;
		}
	}
	
	@Override
	public void addNotify(){
		super.addNotify();
		
		if(loop == null) {
			loop = new Thread(this);
			addKeyListener(this);
			loop.start();
		}
	}
	
	public void update(){
		if(left) {
			x -= 4;
		}
		else if(right) {
			x += 4;
		}
		
		if(up) {
			y -= 4;
		}
		else if(down) {
			y += 4;
		}

	}
	
	//without double buffering ! direct draw !
	public void draw(){
		
		Graphics2D g = (Graphics2D) getGraphics();
		
		//draw map
		for (int row = 0; row < map.length; row++) {
			for (int col = 0; col < map[row].length; col++) {
				if(map[row][col] == 1) {
					g.setColor(Color.BLACK);
				}
				if(map[row][col] == 0) {
					g.setColor(Color.WHITE);
				}
				g.fillRect(col * tileSize - x, row * tileSize - y, tileSize, tileSize);
			}
		}
		
		//draw Player
		g.setColor(Color.RED);
		g.fillRect(WIDTH / 2 - width / 2, HEIGHT / 2 - height / 2, width, height);
		
		//draw info
		g.drawString("Cord. : " + x + "|" + y, WIDTH - 100, 20);
		g.drawString("Pos. : " + y / tileSize + "|" + x / tileSize, WIDTH - 100, 40);
		
	}


	@Override
	public void run(){
		
		while(true){
			
			update();
			draw();
			
			try {
				Thread.sleep(100);
			}
			catch (InterruptedException ex) {
				ex.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args){
		JFrame f = new JFrame();
		f.setDefaultCloseOperation(2);
		f.setContentPane(new Foo());
		f.pack();
		f.setLocationRelativeTo(null);
		f.setVisible(true);
		
	}
}
 
Zuletzt bearbeitet:

Androbin

Bekanntes Mitglied
kaoZ hat gesagt.:
Ich habe nun mal die Map vergrößert, hier wird der Player fix in die Mitte des Sichtbaren bereiches gezeichnet und die map anhand der x und y koordinaten bewegt,

(Das ist, soweit ich es nachvollziehen kann,nicht mein Ziel)
falls du sowas meinstest

...
[/SPOILER]

Du willst das Scrolling wohl so implementieren, dass nur gescrollt wird, wenn der Spieler dem Rand des Sichtfeldes auf eine bestimmte Distanz nahekommt, oder?

In meinem Falle sieht das ganze so aus:

Java:
public void scroll() {

if ( spieler.x + world.getSX() < 0.2 * world.getWidth() )
world.setSX( (int) ( 0.2 * world.getWidth() + 0.5 ) - spieler.x );
		
else if ( spieler.x + spieler.width + world.getSX() > 0.8 * world.getWidth() )
world.setSX( (int) ( 0.8 * world.getWidth() + 0.5 ) - ( spieler.x + spieler.width - 1 ) );
		
if ( spieler.y + world.getSY() < 0.2 * world.getHeight() )
world.setSY( (int) ( 0.2 * world.getHeight() + 0.5 ) - spieler.y );
		
else if ( spieler.y + spieler.height + world.getSY() > 0.8 * world.getHeight() )
world.setSY( (int) ( 0.8 * world.getHeight() + 0.5 ) - ( spieler.y + spieler.height - 1 ) );

}

Schreib' es dir deinen Bedürfnissen entsprechend um und bau es ein!

Keyone94 hat gesagt.:
falls du willst kannst du später noch einbauen, dass wenn man sich dem Rand nähert, die Position des Spielers verändert wird anstelle der Map (man also am Rand der Wand entgegen läuft

Also ich verändere beides, die Position des Spielers und die Scrolling-Variablen "sX" und "sY"!
 
Zuletzt bearbeitet:

lord239123

Bekanntes Mitglied
So wie das auf dem Bild aussieht, hast du deine Welt rasterartig erstellt.
Das kannst du auch gleich ausnutzen und zum Beispiel sagen, dass der Spieler sich beim drücken auf die entsprechende Taste entsprechend viele Felder bewegt.
Bevor der Spieler sich allerdings bewegt, muss das Programm testen, ob das entsprechende Feld belegt ist(schwarzes Feld, repräsentiert durch 1) oder ob der Spieler sich auf das Feld bewegen kann(weißes Feld, repräsentiert durch 0).
Die Felder speicherst du intern in einem 2 dimensionalem Array, in das du immer nur reinschaust.

Bei größeren Maps ergibt sich dabei auch der Vorteil, dass du nicht immer die gesamte Map geladen haben musst, um dieses System anzuwenden.
Das Rastersystem ist für den Vorhaben das meiner Meinung nach beste System, da du nicht jeden einzelnen Punkt prüfen musst, sondern immer nur den linken oberen Punkt deines Spielers!:)
 

kaoZ

Top Contributor
Selbstverständlich könnte man das Movement auch so implementieren das man immer nur ein Tile weitergehen kann, dies ist aber auch nicht mein Ziel ,

Das Tilemap scrolling funktioniert mittlerweile auch soweit, allerdings passt die Position noch nicht ganz ^^

in der Klasse LevelOne welche alle relevanten Informationen über player map und co enthält ,

wird beim Initialisieren die map auf die Position x = 0, y = 0 gezeichnet,

der Player wird an position x = 100, y = 100 gezeichnet,

die map wird in deren draw methode so gezeichnet :

Java:
g.drawImage(tiles[r][c].getImage(),(int)x + col * tileSize,(int)y + row * tileSize, null);

der Player wird folgendermaßen gezeichnet :

Java:
g.fillRect((int)(x + mapX - width / 2), (int)(y + mapY - height / 2), width, height);

mapX und mapY sind die aktuellen koordinaten der map.

Wenn ich nun in der update methode der Klasse LevelOne folgendes schreibe

Java:
tileMap.setPosition(GamePanel.WIDTH / 2 - player.getX(), GamePanel.HEIGHT / 2 - player.getY());

funktionieren scrolling der map und des players , allerdings wird es dann logischerweise so dargestellt :



setze ich die Position so nicht , passt zwar die map position wirder , aber scrollt logischerweise nicht mit , das movement des players funktioniert natürlich weiterhin, sieht dann so aus



unabhängig von der Kollisionsabfrage muss das scrolling von map und player ja trotzdem funktionieren, und ich muss ja die map um eben diese koordinaten welcher der player aktuell hat in die entgegen gesetzte Richtung verschieben, allerdings find ich den Fehler / Denkfehler grade nicht, vielleicht kann mir ja nochmal jemand auf die Sprünge helfen

Hier nochmal die kompletten klassen :

Java:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import javax.imageio.ImageIO;
import eflow.game.GamePanel;
import eflow.game.drawables.Drawable;


public class TileMap implements Drawable{
	
	//position
	private double x;
	private double y;
	
	//attributes
	private int tileSize;
	private int width;
	private int height;
	private int map[][];
	private int numRows;
	private int numCols;
	private int xOffset;
	private int yOffset;
	
	//tileset
	private BufferedImage tileSet;
	private Tile[][] tiles;
	private int numTilesAcross;
	
	
	public TileMap(int tileSize){
		this.tileSize = tileSize;
	}
	
	public void loadMap(String path){
		
		InputStreamReader in;
		BufferedReader reader;
		
		try {
			in = new InputStreamReader(getClass().getResourceAsStream(path));
			reader = new BufferedReader(in);
			
			numRows = Integer.parseInt(reader.readLine());
			numCols = Integer.parseInt(reader.readLine());
			
			map = new int[numRows][numCols];
			
			width = numCols * tileSize;
			height = numRows * tileSize;
			
			xOffset = GamePanel.WIDTH / tileSize;
			yOffset = GamePanel.HEIGHT / tileSize;
			
			String delimiter = "\\s+";
			
			for (int row = 0; row < numRows; row++) {
				String line = reader.readLine();
				String[] tokens = line.split(delimiter);
				for (int col = 0; col < numCols; col++) {
					map[row][col] = Integer.parseInt(tokens[col]);
				}
			}
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	public void loadTileSet(String path){
		
		try {
			tileSet = ImageIO.read(getClass().getResourceAsStream(path));
			numTilesAcross = tileSet.getWidth() / tileSize;
			
			tiles = new Tile[2][numTilesAcross];
			
			BufferedImage subImage;
			
			for (int col = 0; col < numTilesAcross; col++) {
				subImage = tileSet.getSubimage(col * tileSize, 0, tileSize, tileSize);
				tiles[0][col] = new Tile(subImage, Tile.NORMAL);
				
				subImage = tileSet.getSubimage(col * tileSize, tileSize, tileSize, tileSize);
				tiles[1][col] = new Tile(subImage, Tile.BLOCKED);
			}
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	@Override
	public void update(){
		
	}

	//drawing whole map 
	@Override
	public void draw(Graphics g){
		
		for (int row = 0; row < numRows - 1; row++) {
			for (int col = 0; col < numCols - 1; col++) {
				
				int rc = map[row][col];
				int r = rc / numTilesAcross;
				int c = rc % numTilesAcross;
				
				g.drawImage(tiles[r][c].getImage(),(int)x + col * tileSize,(int)y + row * tileSize, null);
			}
		}
	}
	
	public int getColTile(double x){
		return (int)x / tileSize;
	}
	
	public int getRowTile(double y){
		return (int)y / tileSize;
	}
	
	public int getTileType(int row, int col){
		int rc = map[row][col];
		int r = rc / numTilesAcross;
		int c = rc % numTilesAcross;
		
		return tiles[r][c].getType();
	}
	
	public void setPosition(double x, double y){
		this.x += (x - this.x);
		this.y += (y - this.y);
	}

	public int getX()				{return (int)x;}
	public int getY()				{return (int)y;}
	public int getTileSize()		{return tileSize;}
	public int getWidth()			{return width;}
	public int getHeight()			{return height;}
	public int getXOffset()			{return xOffset;}
	public int getYOffset()			{return yOffset;}
	
}

Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import eflow.game.sprites.TileMap;


public class Player extends MapObject{
	
	public Player(TileMap map){
		super(map);
		
		width	 = 20;
		height	 = 20;
		
		moveSpeed	 = 0.3;
		maxSpeed	 = 4.2;
		fallSpeed	 = 0.15;
		maxFallSpeed = 11.9;
		stopSpeed 	 = 3.0;
		jumpStart 	 = -4.8;
	}
	
	private void getNextPosition(){
		
		//left + right movement
		if(right) {
			dx += moveSpeed;
			if(dx < maxSpeed) {
				dx = maxSpeed;
			}
		}
		else if(left) {
			dx -= moveSpeed;
			if(dx > -maxSpeed) {
				dx = - maxSpeed;
			}
		}
		else {
			if(dx > 0) {
				dx -= stopSpeed;
				if(dx < 0) {
					dx = 0;
				}
			}
			if(dx < 0) {
				dx += stopSpeed;
				if(dx > 0) {
					dx = 0;
				}
			}
		}
		
		//jumping
		if(jumping) {
			
		}
		
		if(falling) {
			
		}
	}

	@Override
	public void update(){
		
		getNextPosition();
		checkTileMapCollision();
		setPosition(tempx,tempy);
	}
	
	@Override
	public void draw(Graphics g){
		
		setMapPosition();
		
		g.setColor(Color.RED);
		g.fillRect((int)(x + mapX - width / 2), (int)(y + mapY - height / 2), width, height);
	}

	@Override
	public void keyPressed(int key){
		if(key == KeyEvent.VK_W) {
			
		}
		if(key == KeyEvent.VK_A) {
			setLeft(true);
		}
		if(key == KeyEvent.VK_S) {
			
		}
		if(key == KeyEvent.VK_D) {
			setRight(true);
		}
		if(key == KeyEvent.VK_SPACE) {
			setJumping(true);
		}
	}

	@Override
	public void keyReleased(int key){
		if(key == KeyEvent.VK_W) {
			
		}
		if(key == KeyEvent.VK_A) {
			setLeft(false);
		}
		if(key == KeyEvent.VK_S) {
			
		}
		if(key == KeyEvent.VK_D) {
			setRight(false);
		}
		if(key == KeyEvent.VK_SPACE) {
			setJumping(false);
		}
	}
}

Java:
import java.awt.Graphics;
import java.awt.Rectangle;
import eflow.game.control.Moveable;
import eflow.game.drawables.Drawable;
import eflow.game.sprites.TileMap;

public abstract class MapObject implements Drawable, Moveable{

	//dimensions
	protected int width;
	protected int height;
	
	//position
	protected double x;
	protected double y;
	
	//collision
	protected double tempx;
	protected double tempy;
	
	//vector
	protected double dx;
	protected double dy;
	
	//map
	protected TileMap tileMap;
	protected int currCol;
	protected int currRow;
	protected int tileSize;
	protected double mapX;
	protected double mapY;

	//movement
	protected boolean left;
	protected boolean right;
	protected boolean up;
	protected boolean down;
	protected boolean jumping;
	protected boolean falling;
	
	//movement attributes
	protected double moveSpeed;
	protected double maxSpeed;
	protected double stopSpeed;
	protected double fallSpeed;
	protected double maxFallSpeed;

	protected double jumpStart;
	
	public MapObject(TileMap map){
		tileMap = map;
		tileSize = map.getTileSize();
	}

	@Override
	public void update(){
		x += dx;
		y += dy;
	}

	@Override
	public void draw(Graphics g){}	
	
	public void setPosition(double x, double y){
		this.x = x;
		this.y = y;
	}
	
	public void setVector(double dx, double dy){
		this.dx = dx;
		this.dy = dy;
	}
	
	public void setMapPosition(){
		mapX = tileMap.getX();
		mapY = tileMap.getY();
	}
	
	public Rectangle getBounds(){
		return new Rectangle((int)x, (int)y, width, height);
	}
	
	public boolean intersects(MapObject o){
		Rectangle r1 = getBounds();
		Rectangle r2 = o.getBounds();
		
		return r1.intersects(r2);
	}
	
	public void checkTileMapCollision(){
		
		//without World collision! 
		
		tempx = x;
		tempy = y;
		
		tempx += dx;
		tempy += dy;
	}
	
	public void setLeft(boolean b)			{left = b;}
	public void setRight(boolean b)			{right = b;}
	public void setJumping(boolean b){
		if(!falling) {
			jumping = b;
		}
	}
	
	public int getX()						{return (int)x;}
	public int getY()						{return (int)y;}
}
 

Androbin

Bekanntes Mitglied
kaoZ hat gesagt.:
der Player wird folgendermaßen gezeichnet :
Java:
g.fillRect((int)(x + mapX - width / 2), (int)(y + mapY - height / 2), width, height);

Sollte das nicht so heißen?:
Java:
g.fillRect( (int) ( x + mapX ), (int) ( y + mapY ), width, height );
WIESO IN JAVA'S NAMEN ZIEHST DU "WIDTH / 2"/"HEIGHT / 2" AB ???
 

kaoZ

Top Contributor
Weil der Player mittig, an die Koordinaten gezeichnet wird, das ist auch nicht das Problem ;)
Und macht auch nicht wirklich einen Unterschied, ich ziehe ja nur die Größe und Höhe des Players /2 ab, sprich wäre es ein fadenkreuz säße er mittig drauf und nicht mit der oberen linken Ecke
 
Zuletzt bearbeitet:

Androbin

Bekanntes Mitglied
Ja, aber damit versaust du dir deine ganze Kollision:
Die X/Y-Koordinaten beginnen schließlich an der linken oberen ECKE
und nicht etwa im MITTELPUNKT, sprich:
Du müsstest die deine komplette Kollision umstellen,
oder WILLST du etwa all das NOCHMAL von Hand implementieren?
Fazit: HÖR ENDLICH AUF, AM KOORDINATEN-SYSTEM HERUMZUSCHRAUBEN
 

kaoZ

Top Contributor
Mag schon sein, und ja ich wollte die kollisionsabfragen eh nochmal komplett neu implementieren ( rein zu lern und übungszwecken), wenn ich so überall vorgehe , macht es doch aber keinen unterschied.

Hilft mir aber trotzdem immer noch nicht bei meinem tilemap scolling problem ^^, bzw dessen Platzierung / bzw. an welcher stelle sie gezeichnet wird, und wieso.
 
Zuletzt bearbeitet:

lord239123

Bekanntes Mitglied
Eine Möglichkeit für dein Scrollingsystem wäre folgende:
Erstelle am besten ein Panel, welches die Größe der fertigen Map hat.
Wenn sich jetzt der Spieler bewegen soll, bewegst du das Panel in die eine Richtung und den Spieler genauso weit in die andere Richtung.
Um das ganze performanter zu gestalten, kannst du festlegen, dass immer nur die Felder um den Spieler herum gezeichnet werden sollen.
Da deine Map vermutlich nicht allzu groß sein wird, kannst du ruhig alle Felder zeichnen.

Bei meinem Pokemon Spiel, welches ebenfalls eine Rasterartige Welt besitzt, funktioniert das auf diese Weise zumindest.

Ich habe mir deinen Quellcode nicht komplet tdurchgelesen, weshalb es evtl ein bisschen Anpasungsbedarf gibt.
 

kaoZ

Top Contributor
Das mit dem Panel in die eine und dem player in die andere richtung hatte ich bereits versucht, allerdings war es so das das irgendwann der player nach rechts aus dem bild lieft, vermutlich weil der movespeed nicht konstant geblieben ist sondern bis zu einem maximum inkrementiert wird, dies müsste ich ja dann ja ebenso auf die map umsetzen , oder sehe ich das falsch ?

sprich der player bewegt sich mit einer gewissen Anzahl an pixeln ( movespeed) nach rechts und die map dann invertiert, also quasi nach links mit eben dieser Geschwindigkeit bzw. anzahl an pixeln. ( bzw. wird die map dann an / ab den dementsprechenden koordinaten gezeichnet .
 

Androbin

Bekanntes Mitglied
1. ist die Idee mit dem Panel eine furchtbare Idee und

2. zurück zur Kollision (width/2, height/2):
kaoZ hat gesagt.:
wenn ich so überall vorgehe, macht es doch aber keinen unterschied.
Theoretisch ja, aber bedenke folgendes:

2.1 Du machst es dir unnötig kompliziert, denn
2.2 Frägst du die Felder, auf denen der Spieler "steht" ja so ab:
Code:
Code:
X/Y-Koordinate / Feld-Größe
, was dir normalerweise angibt,
auf welchem Feld sich die linke obere Ecke des Spielers finden lässt,
dementsprechend
Code:
( X/Y-Koordinate + Breite/Höhe ) / Feld-Größe
für rechts unten

Das funktioniert aber [STRIKE]leider[/STRIKE] nicht, so wie du es machst
 

kaoZ

Top Contributor
Ich werde es am wochenende einfach nochmal sauber und ohne schnickschnack neu implementieren und dann schau ich mal weiter :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A DoodleJump programmieren: Kollisionsabfrage Spiele- und Multimedia-Programmierung 6
T Problem bei Kollisionsabfrage Spiele- und Multimedia-Programmierung 4
S Polygon Kollisionsabfrage Spiele- und Multimedia-Programmierung 2
RalleYTN Erweiterte Kollisionsabfrage Spiele- und Multimedia-Programmierung 7
S Kollisionsabfrage zwischen Rechteck und Polygon Spiele- und Multimedia-Programmierung 1
J Java Kollisionsabfrage Spiele- und Multimedia-Programmierung 21
T Problem mit Kollisionsabfrage der NPC Spiele- und Multimedia-Programmierung 1
F Kollisionsabfrage bei schnellen Objekten Spiele- und Multimedia-Programmierung 2
J Problem bei pixelgenauer Kollisionsabfrage Spiele- und Multimedia-Programmierung 10
M Kollisionsabfrage Spiele- und Multimedia-Programmierung 7
N Quake - Kollisionsabfrage Spiele- und Multimedia-Programmierung 21
N Problem mit Kollisionsabfrage beim Fallen Jump & Run Spiele- und Multimedia-Programmierung 5
R Kollisionsabfrage haut nicht hin Spiele- und Multimedia-Programmierung 15
Gossi Quaxlis 2D Tutorial....Probleme nach hinzufügen der Kollisionsabfrage Spiele- und Multimedia-Programmierung 16
U Jump n' Run 2D Geometrie und Kollisionsabfrage? Spiele- und Multimedia-Programmierung 11
baddestpoet Problem mit Kollisionsabfrage Spiele- und Multimedia-Programmierung 18
D Kollisionsabfrage von 2 Autos Spiele- und Multimedia-Programmierung 2
G Kollisionsabfrage (Mario klon) Spiele- und Multimedia-Programmierung 6
gieser Buggy Kollisionsabfrage Spiele- und Multimedia-Programmierung 4
masta // thomas Kollisionsabfrage - inspiriert durch "pixelgenaue Kolli Spiele- und Multimedia-Programmierung 13
gieser pixelgenaue Kollisionsabfrage der Kreise Spiele- und Multimedia-Programmierung 9
T Kollisionsabfrage von einem Stein mit einem Ball Spiele- und Multimedia-Programmierung 5
N Kollisionsabfrage Spiele- und Multimedia-Programmierung 6
D Jump and Run Game -- Kollisionsabfrage Spiele- und Multimedia-Programmierung 30
J Kollisionsabfrage Ball <-> Paddle Spiele- und Multimedia-Programmierung 2
L Hörtest programmieren und implementieren Spiele- und Multimedia-Programmierung 2
Arif Maus-Objekt im Player Klasse implementieren !? Spiele- und Multimedia-Programmierung 2

Ähnliche Java Themen

Neue Themen


Oben