I need help calling different classes.
I want to create a class for, a menu, the game, an option menu, credits etc.
I just need to know how to call a different class
//Ok i have edited my post, hope i provided enough information.
game class
//Add Screens
private MenuScreen menuScreen;
public final static int MENU=0;
public void changeScreens(int screen){
switch(screen){
case MENU:
if(menuScreen==null){
menuScreen=new MenuScreen(this);
}
}
}
//Render (When you click on the button)
if(drawplay) {
menuScreen=new MenuScreen(this);
setScreen( menuScreen);
//MenuScreen Class
ublic class MenuScreen implements Screen {
private rugby parent;
public MenuScreen(rugby rugby){
parent = rugby;
}
#Override
public void render(float delta) {
Gdx.app.log( "Play","Play" );
}
Related
I have a world that is the GameScreen (20ish objects) which lays all objects as intended. However, when I get GameOver I want to be a blank canvas with just the background and some new objects(a couple objects), but all the existing objects from GameScreen carry over and I cant figure out how to stop it or delete them on the GameOver screen
public class GameScreen extends World
{
public GameScreen()
{
super(600, 400, 1);
prepare();
}
private void prepare()
{
addObjects.......
}
}
public class GameLost extends GameScreen
{
public GameLost()
{
removeObjects(GameScreen);
prepare();
}
private void prepare()
{
addObjects...
}
I'm pretty sure you don't want GameLost extends GameScreen.
Do
class GameLost {
private Background bg;
public void paint() {
paint(bg);
}
}
class GameScreen {
private Background bg;
private List<GameObjects>...
public void paint() {
paint(bg);
gameObjects.forEach(go -> paint(go));
}
}
which makes it easy to move over the background from game screen to game over screen, without the game objects.
I am having a problem with libGDX where when I resume the application after exiting with the back button, I get only a white screen.
The actual app runs, accepts touch input, and plays sounds, but the screen is just white.
I have read that keeping static references to Textures may cause this problem but I am not doing that.
Below is a simplified version of how my asset code works.
public class GdxGame extends Game {
private Assets assets;
#Override
public void onCreate() {
assets = new Asstes();
assets.startLoading();
/*
*Within SplashScreen, GdxGame.getAssets() is accessed, and
*manager.update() is called
*/
setScreen(new SplashScreen());
}
#Override
public void dispose() {
assets.dispose();
assets = null;
}
//Perhaps a problem??
public static Assets getAssets() {
return ((GdxGame) Gdx.app.getApplicationListener()).assets;
}
}
public class Assets implements Disposable{
private AssetManager manager;
public Assets() {
manager = new AssetManager();
}
public void startLoading() {
manager.load(....);
}
#Override
public void dispose() {
manager.dispose();
}
}
Upon returning to the application after the back button is pressed, the AssetManager is recreated, the SplashScreen is reopened (as white), and the AssetManager updates until all assets are reloaded (takes about 2 seconds).
So when the application is reopened, a new AssetManager is loading all of the necessary textures, but for some reason everything is still white.
Could it have something to do with how I access the AssetManager from my UI and Game classes?
//In GdxGame
public Assets getAssets() {
return ((GdxGame) Gdx.app.getApplicationListener()).assets;
}
That is the only place where I could see something going wrong, but even still, I don't understand what could be wrong with that.
Any help would be much appreciated.
Edit:
Here is the SplashScreen class. This makes the issue even more confusing. In the SplashScreen class I load, draw, and dispose a new Texture for the logo. Nothing to do with the AssetManager. Returning after the back button is pressed, this new Texture does not appear either.
public class SplashScreen extends Screen {
private Texture logo;
private Assets assets;
#Override
public void show() {
assets = GdxGame.getAssets();
logo = new Texture(Gdx.files.internal("data/logo.png"));
}
#Override
public void render(float delta) {
super.render(float delta);
if(assets.load()) {
//Switch screens
}
//getBatch() is the same form as getAssets() ((GdxGame) Gdx.app.getApplicationListener()).batch)
GdxGame.getBatch().draw(logo, 100, 100, 250, 250);
}
#Override
public void hide() {
super.hide();
logo.dispose();
}
}
It turns out the issue was to do with how I was managing screens. I had a convenience method in my GdxGame class that allowed me to switch screens based on a ScreenType enum.
Within the enum, I would create a new screen with reflection, given the screen's class in the enum constructor.
The problem is that I stored the screens in the enums, and only created them once. This means that I was keeping and using screens from the old context when I returned after pressing back.
To solve this, I simply had to change it so that a new screen is created every time the enum is accessed, instead of storing one at the start.
I want to develop a simple interactive game (like arcanoid). I already have implemented a menu and different views, and now I need to develop the actually game (draw flying ball, some movable platform) and I don't know how to do this. I need something like canvas where I can draw my graphic each frame.
I have tryed to implement this with Canvas and Timer. But it doesn't want update graphic itself, but only when user clicks on screen or similar. Also I saw com.google.gwt.canvas.client.Canvas, but I cannot understand how to use it in Vaadin application.
So my question is next: is it possible to draw some graphic each frame with high framerate in any way? If possible, how can I do this?
P.S. I use the Vaadin 7.3.3.
ADDED LATER:
Here is a link to my educational project with implementation below.
I'll be glad if it helps someone.
ORIGINAL ANSWER:
Well... I found the solution myself. First of all, I have created my own widget - "client side" component (according to this article).
Client side part:
public class GWTMyCanvasWidget extends Composite {
public static final String CLASSNAME = "mycomponent";
private static final int FRAMERATE = 30;
public GWTMyCanvasWidget() {
canvas = Canvas.createIfSupported();
initWidget(canvas);
setStyleName(CLASSNAME);
}
Connector:
#Connect(MyCanvas.class)
public class MyCanvasConnector extends AbstractComponentConnector {
#Override
public Widget getWidget() {
return (GWTMyCanvasWidget) super.getWidget();
}
#Override
protected Widget createWidget() {
return GWT.create(GWTMyCanvasWidget.class);
}
}
Server side part:
public class MyCanvas extends AbstractComponent {
#Override
public MyCanvasState getState() {
return (MyCanvasState) super.getState();
}
}
Then I just add MyCanvas component on my View:
private void createCanvas() {
MyCanvas canvas = new MyCanvas();
addComponent(canvas);
canvas.setSizeFull();
}
And now I can draw anything on Canvas (on client side in GWTMyCanvasWidget) with great performance =). Example:
public class GWTMyCanvasWidget extends Composite {
public static final String CLASSNAME = "mycomponent";
private static final int FRAMERATE = 30;
private Canvas canvas;
private Platform platform;
private int textX;
public GWTMyCanvasWidget() {
canvas = Canvas.createIfSupported();
canvas.addMouseMoveHandler(new MouseMoveHandler() {
#Override
public void onMouseMove(MouseMoveEvent event) {
if (platform != null) {
platform.setCenterX(event.getX());
}
}
});
initWidget(canvas);
Window.addResizeHandler(new ResizeHandler() {
#Override
public void onResize(ResizeEvent resizeEvent) {
resizeCanvas(resizeEvent.getWidth(), resizeEvent.getHeight());
}
});
initGameTimer();
resizeCanvas(Window.getClientWidth(), Window.getClientHeight());
setStyleName(CLASSNAME);
platform = createPlatform();
}
private void resizeCanvas(int width, int height) {
canvas.setWidth(width + "px");
canvas.setCoordinateSpaceWidth(width);
canvas.setHeight(height + "px");
canvas.setCoordinateSpaceHeight(height);
}
private void initGameTimer() {
Timer timer = new Timer() {
#Override
public void run() {
drawCanvas();
}
};
timer.scheduleRepeating(1000 / FRAMERATE);
}
private void drawCanvas() {
canvas.getContext2d().clearRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
drawPlatform();
}
private Platform createPlatform() {
Platform platform = new Platform();
platform.setY(Window.getClientHeight());
return platform;
}
private void drawPlatform() {
canvas.getContext2d().fillRect(platform.getCenterX() - platform.getWidth() / 2, platform.getY() - 100, platform.getWidth(), platform.getHeight());
}
}
I want to be able to have a canvas component that adds spots to places where the user double clicks, when a spot is added, and then I want to be able to notify the listbox placed in the main frame that a spot has been added.
My knowledge of event broadcasting is poor, is there a better way of doing this?
Main class: initialize drawing component:
will this be best for an unnamed inner class?
private JList lbx;
private DefaultListModel<String> lbxModel;
private DrawComp draw;
public static void main(String args[]) {
draw.addListener(new DrawCompListener() {
#Override
public void spotAdded(DrawComp source, Spot spot) {
lbxModel.addElement("spot+" added");
}
});
}
interface that will be passed through to the queue:
public interface DrawCompListener {
void spotAdded(DrawComp source, Spot spot);
Queue Class that will implement the interface: (should this be here?)
public class DrawCompListenerQueue implements DrawCompListener {
private ArrayList<DrawCompListener> listeners = new ArrayList<DrawCompListener>();
public void addListener(DrawCompListener listener) {
listeners.add(listener);
}
#Override
public void spotAdded(DrawComp source, Spot spot) {
for(DrawCompListener listener : listeners) {
listener.spotAdded(source, spot);
}
}
The actual drawing component to place the spots and pass through the info to the main class for the Jlist
public class DrawComp extends JPanel implements MouseListener {
private Vector<Spot> spots = new Vector<Spot>();
private DrawCompListenerQueue listenerQ = new DrawCompListenerQueue();
public void addListener(DrawCompListener listener) {
listenerQ.addListener(listener);
}
adding a spot:
public void mouseClicked(MouseEvent e) {
// left-click = add spot
if ((e.getButton() == MouseEvent.BUTTON1) && (e.getClickCount() == 2)) {
// add spot
Spot s = new Spot();
s.p = e.getPoint();
spots.add(s);
repaint();
// notify listeners
listenerQ.spotAdded(this, s);
Do not reinvent the wheel use the Glazed list lib.
I'm writing a simple pikachu game in Java, and I use swing.Timer with JProgress Bar, my code is like this:
public static void TimeBarListener(final View scr){
ActionListener updateProBar = new ActionListener() {
#Override
public void actionPerformed(ActionEvent actionEvent) {
int val = scr.timeBar.getValue();
if (val <= 0) {
scr.gameOver();
scr.timer = null;
return;
}
scr.timeBar.setValue(--val);
}
};
int t = n*400;
scr.timer = new Timer(t, updateProBar);
}
The "src" here is a class which extends JFrame to display the game I wrote, and 'n' is the number of pikachu pieces on a level. It works perfectly but after I add "timer", there are lots of problems occured:
I set the variable 't' change by level, but seems like it doesn't work ( I test the value, it was the right value but seems like 'timer' could'n get it). The time ran out too fast, faster if I click more on the pieces, and even if I set it longer it didn't change anything.
When I clicked "New Game" the second times, timer ran out even faster. But if I close the programs and then run again, the time return normal.
If the time ran out and then I click the "New Game" button again, It appears for 1 second then return to the "Game Over screen". Sometimes it works, but "IndexArrayOutOfBounds" Ecception appears.
I want to use the "Pause" button, which means that timer must pause and then continue to run, too. Is there anyway that I can do it?
I guess my problems are based on the code
if (val <= 0) {
scr.gameOver();
scr.timer = null;
return;
}
which makes the Game Over screen appears if the timer run out. But I'm new to this and I cant understand how I works, so I can't think of any solutions myself, or maybe it's not the problem.
Hope that I'll get some helps from you guys. Thanks a lot :)
Your problem is that you don't use correct architecture pattern. You should separate your business logic from your presentation. Also you should store variables (like time_left) in model, not in the controller (i.e. ActionListener). Please read about: Model View Controller pattern. It's a basic pattern and it'll solve most of yours problems.
Basic Example
Editor.java - main class
public class Editor {
public static void main(String[] args) {
Model model = new Model();
View view = new View(model);
new Controller(model, view);
}
}
View.java
public class View extends JFrame {
private Model model;
private JButton btn;
public View(Model model) {
this.model = model;
this.btn = new JButton("Test");
}
public void addViewControlListener(ActionListener al){
btn.addActionListener(al);
}
}
Controller.java
public class Controller {
public Controller(Model model, View view) {
view.addViewControlListener(new ViewControlListener(model, view));
}
}
ViewControlListener.java - implements ActionListener
public class ViewControlListener implements ActionListener {
private Model model;
private View view;
public ViewControlListener(Model model, View view){
this.model = model;
this.view = view;
}
public void actionPerformed(ActionEvent e) {
//update model
//refresh view
}
}
As you can see I have the one place (Controller.java) where I create listeners and add
these to components in view. You created multiple instances of the same listeners and lost control.
Also my ActionListener (ViewControlListener.java) holds instances of model and view, so it can update variables in model and refresh view.
Your application
And now something more about your application. You need thread (not realy action listener) that would decrement time variable and update view to show actual state (but only when game is active).
So you could create in model leftTime and isActive variables with setters and getters:
private int leftTime;
private boolean isActive;
public int getLeftTime() {
return leftTime;
}
public void setLeftTime(int leftTime) {
this.leftTime = leftTime;
}
public void decLeftTime() {
this.leftTime--;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean isActive) {
this.isActive = isActive;
}
And create thread that decrement time every second and repaint the view:
public class Timer extends Thread {
private Model model;
private View view;
public Timer(Model model, View view) {
this.model = model;
this.view = view;
}
public void run() {
while(true) { //could be better
if(model.isActive()) {
model.decLeftTime();
view.repaint();
}
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Then create and start that thread in Controller:
public class Controller {
public Controller(Model model, View view) {
view.addViewControlListener(new ViewControlListener(model, view));
...
Timer timer = new Timer(model, view);
timer.start();
}
}
In view you would add some component that shows left time from model and that's it.
PS do not forget set leftTime on game start.