I am a noob learning basic game programming in Slick 2D Using Eclipse and java
I am following a tutorial at https://www.youtube.com/watch?annotation_id=annotation_871076&feature=iv&src_vid=NoksHLldlcM&v=oWm5JY6IlUo and when i hit run it does not work. I get this error
Exception in thread "main" java.lang.RuntimeException: Resource not found: testdata/alphamap.png
at org.newdawn.slick.util.ResourceLoader.getResourceAsStream(ResourceLoader.java:69)
at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:169)
at org.newdawn.slick.Image.<init>(Image.java:196)
at org.newdawn.slick.Image.<init>(Image.java:170)
at org.newdawn.slick.Image.<init>(Image.java:158)
at org.newdawn.slick.Image.<init>(Image.java:136)
at org.newdawn.slick.tests.AlphaMapTest.init(AlphaMapTest.java:33)
at org.newdawn.slick.AppGameContainer.setup(AppGameContainer.java:390)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:314)
at org.newdawn.slick.tests.AlphaMapTest.main(AlphaMapTest.java:79)
This is what I am attempting
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
public class Main extends BasicGame{
private static final String Slick2D = null;
public Main(String title) {
super(title);
// TODO Auto-generated constructor stub
}
//this is where execution starts
public static void man(String args[]) throws SlickException {
AppGameContainer app = new AppGameContainer(new Main("First Slick2D"));
app.setDisplayMode(800, 600, false);
app.start();
}
#Override
public void render(GameContainer gc, Graphics g) throws SlickException {
// draw all the graphics
g.fillOval(200, 200, 100, 300)
g.fillRect(300, 200, 100, 200)
g.fillRoundRect(500, 200, 100, 50, 30)
g.drawLine(0, 0, 800, 600)
g.drawString(Welcome to Slick2D, 400, 0)
}
#Override
public void init(GameContainer arg0) throws SlickException {
// load all fonts, graphics, sounds, etc.
}
#Override
public void update(GameContainer arg0, int arg1) throws SlickException {
// game logic (AI, user input)
}
}
it's simply can't find image. check your scr folder for testdata folder and check if it contains alphamap.png (or you can delete some code where you getting and setting this picture)
Slick expects images to be in a folder called images. I'm not sure why, but it does.
Your direcetories should look like this:
\src\Main.java
\images\alphamap.png
If that doesn't work, make sure your directories are properly named and are within the project folder, not the src folder.
Example:
\MyProject\src\Main.java is your source code
\MyProject\images\alphamap.png
Related
I am working on an assignment and I need to first create a simple GUI that displays a picture/gif on it. However I need to use the paintComponent method, which I am struggling with.
Here is the code I have so far:
import javax.swing.*; import java.awt.Graphics.*;
public class HelloGIF extends JFrame {
image1 =Toolkit.getDefaultToolkit().createImage("C:\\Users\\carlo\\Documents\\Carlo's Documents\\ITEC 2610\\Java Files\\HelloGIF\\BT-Thumbsup.gif");
public HelloGIF(String title) {
super(title);
setBounds(75,75,750,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image1, 200, 150, 50,50,this);
}
public static void main(String[] args){
System.out.println("Initializing...");
HelloGIF myApp = new HelloGIF(String.join("+",args));
myApp.setVisible(true);
}
}
At the moment compiling generates an "identfier expected" on "C:\Users\carlo\Documents\Carlo's Documents\ITEC 2610\Java Files\HelloGIF\BT-Thumbsup.gif", pointing to the I in 'HelloGIF'. what declaration should I add? Am I on the right track or am I totally off?
I'm trying to make an overlay for a HTML-based game running in a browser window and created an JFrame which is opaque. I'd like to be able to still play the game whilst having the overlay above the window. I tried some solutions that I've found but those didn't work for me.
I've thought of catching the click-event on my JFrame and "simulating" the click on the game window. But sadly I don't have an idea how thats possible.
My current code is using the JNA libarys to access the position and scale of the window (in my test code Task-Manager).
I'm fine with using another libary or something like that, if it's even possible.
Thats my code so far:
import com.sun.jna.platform.DesktopWindow;
import com.sun.jna.platform.WindowUtils;
import javax.swing.*;
import java.awt.*;
public class Test {
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("title");
frame.setUndecorated(true);
frame.setBackground(new Color(255, 69, 0, 100));
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Rectangle rect = null;
while (true) {
for (DesktopWindow desktopWindow : WindowUtils.getAllWindows(true)) {
if (desktopWindow.getTitle().contains("Task-Manager")) {
rect = desktopWindow.getLocAndSize();
frame.setSize(rect.width - 16, rect.height - 8);
frame.setLocation(rect.x + 8, rect.y);
frame.setVisible(true);
Thread.sleep(10);
}
}
}
}
}
A JFrame is a heavyweight component. There is a window in the host OS GUI system to go with it. The host OS GUI directs mouse events to the window. Perhaps using a lightweight component for your overlay and then disabling mouse events on it would be a better solution.
Your idea of catching the click event and "simulating it" on you game window should be fairly easy. If your JFrame event processing code has a reference to your game engine, it can determine the relative position of the windows and tell your game engine the corresponding point at which it should act as if it received a click. I.e. just call the same method of your game engine for click events that it received normally and also for the simulated ones.
An ugly hack (there is noticeable flicker) would be to hide the window and send the click through with the Robot class... like this:
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.SwingUtilities;
public class ClickThrough extends Frame implements MouseListener, MouseMotionListener {
private final Robot robot;
private Color bgColor = new Color(0x80808080, true);
private Point dragPoint;
public ClickThrough() throws AWTException {
setAlwaysOnTop(true);
robot = new Robot();
}
public static void main(String[] args) throws AWTException {
ClickThrough w = new ClickThrough();
w.setUndecorated(true);
w.setSize(200, 100);
w.setOpacity(0.7f);
w.addMouseListener(w);
w.addMouseMotionListener(w);
w.setVisible(true);
}
#Override
public void paint(Graphics g) {
int w = getWidth();
int h = getHeight();
g.setColor(Color.GRAY);
g.fillRect(0, 0, w, 16);
g.setColor(bgColor);
g.fillRect(0, 16, w, h-16);
g.setColor(Color.BLACK);
g.drawString("Go ahead, click on me...", 20, 50);
}
private void makeHole(MouseEvent e) {
// Tried making a shape with a hole where the mouse was clicked,... didn't work (macOS).
//setShape(windowWithHoleShape);
setVisible(false);
}
private void repairHole(MouseEvent e) {
//setShape(windowShape);
setVisible(true);
}
#Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
// give it a draggable area at the top
if (p.y < 16) {
dragPoint = p;
return;
}
dragPoint = null;
SwingUtilities.convertPointToScreen(p,this);
makeHole(e);
robot.mouseMove(p.x, p.y);
robot.mousePress(InputEvent.getMaskForButton(e.getButton()));
repairHole(e);
}
#Override public void mouseReleased(MouseEvent e) { }
#Override public void mouseClicked(MouseEvent e) { }
#Override public void mouseEntered(MouseEvent e) { }
#Override public void mouseExited(MouseEvent e) { }
#Override
public void mouseDragged(MouseEvent e) {
if (dragPoint != null) {
Point p = e.getPoint();
SwingUtilities.convertPointToScreen(p, this);
p.translate(-dragPoint.x, -dragPoint.y);
setLocation(p);
}
}
#Override
public void mouseMoved(MouseEvent e) { }
}
I tried to see if I could cut a hole in the window by setting the window Shape, but at least on macOS the hole does not allow the mouse events through.
I should also point out that if you switch your GUI framework to JAvaFX, then you have the option of running your HTML-based game UI in a JavaFX WebView, so you can integrate your game and overlay into a single coherent application. You could specifically make your overlay "mouse transparent". IMO that would be a much better approach than hacking around with the mouse events.
i'm new to Slick2d and to this page too, i tried asking the slick forums, but there aren't many people so i couldn't get an answer
Anyway, i've been trying to create a platformer engine in Slick2d java game library, and i was thinking of using the contains and intersects methods of the Shape class.
The thing is, if I want to check if a shape contains any object of any kind (or any object from a specific class), Is there a way to do that? all tutorials i've found explain how to test collision with one single shape, but what if i want to check for any object?
package juegoconslick;
import java.util.ArrayList;
import org.newdawn.slick.*;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
public class JuegoConSlick extends BasicGame {
Jugador player;
Input entrada;
Shape hitbox;
bloque bloq;
ArrayList<bloque> bloques = new ArrayList<>();
public JuegoConSlick(){
super("Mi prueba");
}
public static void main(String[] args) {
AppGameContainer juegito;
try{
juegito = new AppGameContainer(new JuegoConSlick());
juegito.setDisplayMode(630,400,false);
juegito.setMaximumLogicUpdateInterval(60);
juegito.setMaximumLogicUpdateInterval(50);
juegito.setAlwaysRender(true);
juegito.setVSync(true);
juegito.start();
}catch(Exception ex){
System.exit(0);
}
}
#Override
public void init(GameContainer gc) throws SlickException {
player = new Jugador();
hitbox = new Rectangle(player.X, player.Y, 10, 10);
bloq = new bloque(50,50,50,50);
}
#Override
public void update(GameContainer gc, int i) throws SlickException {
intersecta();
Input entrad = gc.getInput();
if(entrad.isKeyDown(Input.KEY_RIGHT) && player.X<600){
player.X+=3;
player.sprite.update(1);
hitbox.setX(player.X);
}
if(entrad.isKeyDown(Input.KEY_LEFT) && player.X>0){
player.X-=3;
player.sprite.update(1);
hitbox.setX(player.X);
}
if(entrad.isKeyDown(Input.KEY_UP) && player.Y>0){
player.Y-=3;
player.sprite.update(1);
hitbox.setY(player.Y);
}
if(entrad.isKeyDown(Input.KEY_DOWN) && player.Y<370){
player.Y+=3;
player.sprite.update(1);
hitbox.setY(player.Y);
}
}
#Override
public void render(GameContainer gc, Graphics grphcs) throws SlickException {
grphcs.draw(bloq.bloque);
grphcs.draw(hitbox);
}
public void intersecta(){
try{
if(hitbox.contains(null)){//i tried checking if it didnt contain any object,
}else{
System.exit(0);
}
}catch(Exception ex){
}
}
}
EDIT: i think i have found a solution, though im not sure if its the most efficient.
basiaclly, i'll save all objects of the same class in an ArrayList:
ArrayList<bloque> bloques = new ArrayList<>();
bloques.add(new bloque(50,50,100,100));
bloques.add(new bloque(100,100,100,100));
Then, what im going to do is check the entire arraylist each time i call the intersects method:
public boolean intersecta(){
boolean devuelve=false;
for(int i=0; i<bloques.size(); i++){
if(hitbox.intersects(bloques.get(i).bloque)){
devuelve=true;
}
}
return devuelve;
}
then im going to use the value i get from intersects to decide whether the player can move or not
public void update(GameContainer gc, int i) throws SlickException {
Input entrad = gc.getInput();
if(entrad.isKeyDown(Input.KEY_RIGHT) && player.X<600 && intersecta()==false){
player.X+=3;
player.sprite.update(1);
hitbox.setX(player.X);
}
and so on with the other keys....
so im not sure if its the best solution, but as far as i have seen it seems to be working. I hope this results useful for others.
I recommend to create a new Class.
This class Needs to inherit an Slick2d Shape, so for instance:
public class ShapeWithReference extends Rectangle{}
This class can have a list or a single object reference:
public class ShapeWithReference Rectangle{
Object reference = new String("hello"); //This is dirty and can be replaced by any object.
}
Since your new class is a Slick2D shape you can now find out whether it is contained by another shape:
Rectangle rec = new Rectangle();
if(rec.contains(ShapeWithReference)){
if(ShapeWithReference.reference instanceof String){
System.out.println((String)ShapeWithReference.reference);
}
}
Contains checks whether the shape really contains another shape. So they are not just intersecting. So that's the first part you check, the second one is whether the reference Attribute of the Shape is for e.g. a String. So if our first rectangle contains our new class and the reference of this class is type of a String this String is supposed to be written in to the console.
Hope this helps or gives you a hint.
EDIT:
public class SlickGame extends BasicGame {
static AppGameContainer appgc;
Rectangle rec;
ShapeWithReference swr;
public SlickGame(String title) {
super(title);
}
#Override
public void render(GameContainer container, Graphics g) throws SlickException {
}
#Override
public void init(GameContainer container) throws SlickException {
rec = new Rectangle(0, 0, 64, 64);
swr = new ShapeWithReference(0, 0, 1, 1);
}
#Override
public void update(GameContainer container, int delta) throws SlickException {
if(rec.intersects(swr)){
if(swr.reference instanceof String){
System.out.println((String)swr.reference);
}
else if(swr.reference instanceof Integer){
System.out.println((Integer)swr.reference);
}
else if(swr.reference instanceof Shape){
Shape temp = (Shape)swr.reference;
System.out.println(temp.getWidth());
}
}
}
public static void main(String[] args) {
try {
appgc = new AppGameContainer(new SlickGame("title"));
appgc.setDisplayMode(800, 600, false);
appgc.setTargetFrameRate(60);
appgc.setFullscreen(false);
appgc.start();
} catch (SlickException ex) {
ex.printStackTrace();
}
}
}
This is the code you should be able to copy & paste directly.
It does work for me, I'm not sure if I got your problem right but after the instanceof Operator you can just add the Class Name and check for it, I added some examples with an Integer and a Shape.
This is the 2nd class:
public class ShapeWithReference extends Rectangle {
private static final long serialVersionUID = 1L;
public ShapeWithReference(float x, float y, float width, float height) {
super(x, y, width, height);
}
Object reference = new String("hello");
}
Does this work for you?
I try to create a mere 2D game in Java and with my researches I found out that the best motor should be Slick.
I used the softaware Tiled to create the map and try to run my Java program to see the result and after many problem of compression I already solved, it turned out that the map is simply false (the tiles are not placed well).
I tried to change see the .tmx code in a text editor but I found nothing to change.
Here's my Java code I run in Eclipse :
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.tiled.*;
public class Lecon_1 extends BasicGame {
GameContainer container;
TiledMap map;
public Lecon_1() {
super("Lesson 1 :: WindowGame");
}
public static void main(String[] args) throws SlickException {
new AppGameContainer(new Lecon_1(), 321, 321, false).start();
}
#Override
public void init(GameContainer container) throws SlickException {
this.container = container;
this.map = new TiledMap("src/map/Essai1.tmx");
}
#Override
public void render(GameContainer container, Graphics g) throws SlickException {
this.map.render(0, 0);
}
#Override
public void update(GameContainer container, int delta) throws SlickException {
}
#Override
public void keyReleased(int key, char c) {
if (Input.KEY_ESCAPE == key) {
container.exit();
}
}
}
The Map I created:
The Map I get after running the code:
I tried many things and search in a lot of websites but nobody seems to have this problem. It may be a problem from the Slick classes but I don't know which one and don't know why. Does anyone have an idea?
Thanks in advance,
Alburkerk
Every couple seconds, the window in which my game is playing will briefly disappear and then reappear. I'm on Windows 7 with the latest version of Slick (a game library for Java). Here's the code I'm using:
package Main;
import org.newdawn.slick.*;
public class Main extends BasicGame{
public Main() {
super("Flashing window issue");
}
#Override
public void init(GameContainer gc) throws SlickException {
}
#Override
public void update(GameContainer gc, int delta) throws SlickException {
}
#Override
public void render(GameContainer gc, Graphics g) throws SlickException {
}
public static void main(String[] args) throws SlickException {
AppGameContainer app = new AppGameContainer(new Main());
app.setDisplayMode(800, 600, false);
app.start();
}
}
How can I fix this issue?
Progress so far:
Update: No solution found yet, but playing the game in fullscreen mode eliminates the flicker. Perhaps this will lead to a solution...
Update 2: Monitering the task manager shows that while the game is flickering its status in the task manager is 'Not Responding'.
Update 3: It seems to only happen when the mouse leaves the game area (regardless of whether the game window loses focus).
Update 4 - Current workaround:
app.setMouseGrabbed(true); // force the mouse to stay in the game area
then in update(...):
// exit when escape is pressed:
if (gc.getInput().isKeyDown(Input.KEY_ESCAPE)) {
gc.exit();
}
I'm not familiar with slick2d but does it have a concept of double buffering? that would be something you would want to turn on if you get flickering.