Slick2d i wykrywanie kolizji

0

Słuchajcie mam bardzo ogólne pytanie à propos wykrywania kolizji.

Używam programu Tiled do tworzenia mapy i przeróżnych obiektów jak drzewa kamienie itp.

Czy znacie jakiś graficzny sposób na wykrywanie kolizji?

Chodzi mi o to bym nie musiał zasysać współrzędnych każdego obiektu będącego częścią mapy by wykryć kolizję bo jest to zbyt wolne i przy większym projekcie nie zda egzaminu.

Jestem świeżakiem w dziedzinie gier dlatego nie chciał bym zacząć w złym stylu.

Proszę o podpowiedzi!

0

collide = map.anythingInPosition(x, y);
Kolizje oparte na pobieraniu pikseli są po prostu złe, działają tylko i wyłącznie w małych grach mających mało kolorów.

0

Gdzieś wyczytałem, że wykrywanie kolizji w przypadku tilemap można bazować na tileset mapy. do poszczególnych tilesets można przypisać wartości blocked.

np. mamy tileset o nazwie trawa gdzie wartość właściwości blocked jest false, czyli postać chodząca po trawie nie będzie blokowana i będzie mogła się swobodnie poruszać.

i tileset o nazwie Skały w którego skład będą wchodzić różnego rodzaju duże skały. Dla właściwości "blocked" tego tileseta będzie przypisana wartość true, co w programie będzie oznaczało że nasza postać nie będzie mogła poruszać się po tego rodzaju tilesach.

Jak to zrealizować?

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package slicktest;

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.util.Rectangle;
import org.newdawn.slick.Animation;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.tiled.TiledMap;

/**
 *
 * @author jarek
 */
public class SlickTest extends BasicGame{
    
    private TiledMap grassMap;
    private Animation sprite, up, down, left, right;
    private float x = 34f, y = 34f;
    // This will keep a list of Tiles that are blocked
    private boolean [][] blocked;
    
    // For collision detection, we have a list of Rectangles you can use to test against
    private ArrayList<Rectangle> blocks;
    
    private static final int SIZE = 34;

    /**
     * @param args the command line arguments
     * @throws org.newdawn.slick.SlickException
     */
    public static void main(String[] args) {
        
        
//        app.setDisplayMode(500, 400, false);
        try {
           AppGameContainer app = new AppGameContainer(new SlickTest());
           app.setDisplayMode(500, 400, false);
           app.start();
        } catch (SlickException ex) {
            Logger.getLogger(SlickTest.class.getName()).log(Level.SEVERE, null, ex);
        }
        
       
    }

    public SlickTest() {
    }

    @Override //tutaj ładujemy zdjecia mapy itp
    public void init(GameContainer gc) throws SlickException {
    
        grassMap = new TiledMap("data/map/grassmap.tmx");
        
        Image[] movementUp = {new Image("data/player/up1.png"), new Image("data/player/up2.png")};
        Image[] movementDown = {new Image("data/player/down1.png"), new Image("data/player/down2.png")};
        Image[] movementLeft = {new Image("data/player/left1.png"), new Image("data/player/left2.png")};
        Image[] movementRight = {new Image("data/player/right1.png"), new Image("data/player/right2.png")};
        int[] duration = {300, 300}; // Ustawiamy jak często ma być rysowana animacja podczas Sprite
        
         /*
        * false variable means do not auto update the animation.
        * By setting it to false animation will update only when
        * the user presses a key.
        */
        up = new Animation(movementUp, duration, false);
        down = new Animation(movementDown, duration, false);
        left = new Animation(movementLeft, duration, false);
        right = new Animation(movementRight, duration, false);
        
        // Oryginalna orientacja postaci (w którą stronę jest obrócona postać standardowo)
        sprite = down; 
        
        // buduje mape kolizji opierającej się na mapie 
         blocked = new boolean[grassMap.getWidth()][grassMap.getHeight()];
 
         
         int layer = 1;
        for (int xAxis=0;xAxis<grassMap.getWidth(); xAxis++)
        {
             for (int yAxis=0;yAxis<grassMap.getHeight(); yAxis++)
             {
                 int tileID = grassMap.getTileId(xAxis, yAxis, layer);
                 String value = grassMap.getTileProperty(tileID, "blocked", "false");
                 if (value.equals("true"))
                 {
                     blocked[xAxis][yAxis] = true;
                     
                      // And create the collision Rectangle
//            blocks.add(new Rectangle((float)xAxis * SIZE, (float)yAxis * SIZE, SIZE, SIZE));
                 }
             }
         }
       
    }

    @Override
    public void update(GameContainer gc, int deltaTime) throws SlickException {
        
      Input input = gc.getInput();
      float fdelta= deltaTime *0.1f;
      
    if (input.isKeyDown(Input.KEY_UP))
    {
        sprite = up;
        if (!(isBlocked(x, y - fdelta) || isBlocked(x + SIZE -1, y - fdelta))){
        sprite.update(deltaTime);
        // The lower the delta the slowest the sprite will animate.
        y -= fdelta;
        }
    }
    else if (input.isKeyDown(Input.KEY_DOWN))
    {
        sprite = down;
        if (!(isBlocked(x, y + SIZE + fdelta) || isBlocked(x+SIZE-1, y + SIZE + fdelta)))
        {
            sprite.update(deltaTime);
            y += fdelta;
        }
    }   
    else if (input.isKeyDown(Input.KEY_LEFT))
    {
        sprite = left;
        if (!(isBlocked(x - fdelta, y) || isBlocked(x - fdelta, y+SIZE-1)))
        {
        sprite.update(deltaTime);
        x -= fdelta;
        }
    }
    else if (input.isKeyDown(Input.KEY_RIGHT))
    {
        sprite = right;
        if (!(isBlocked(x + SIZE + fdelta, y) || isBlocked(x + SIZE + fdelta, y+SIZE-1)))
        {
            sprite.update(deltaTime);
            x += fdelta;
        }
    }
}

    @Override
    public void render(GameContainer gc, Graphics grphcs) throws SlickException {
        
        grassMap.render(0, 0);
        sprite.draw(x, y);
        
    }

    private boolean isBlocked(float x, float y) {
        int xBlock = (int) ((int)x / SIZE);
        int yBlock = (int) ((int)y / SIZE);
        return blocked[xBlock][yBlock];
    }
    
}

blocks.add(new Rectangle((float)xAxis * SIZE, (float)yAxis * SIZE, SIZE, SIZE)); dla tej linii dostaje "incompatible types: possible lossy conversion from float to int" dlaczego?

1 użytkowników online, w tym zalogowanych: 0, gości: 1