To make the snake game, I need to position the snake at the beginning at (0,0), (1.0). I'm working with a coordinate class and a snake class. In the constructor of the coordinate class I set all x and y values to 0. I created an array with coordinates and I want to set the first 2 coordinates manually (method startPositionSnake) because it's the starting position. This is when I get a nullpointerexception. I don't get why this happens because all coordinates are (0,0) by default. (under the screenshots is the used code)
code:
package Snake;
import java.util.Random;
import java.util.Locale;
import java.util.Scanner;
import ui.Event;
import ui.SnakeUserInterface;
import ui.UserInterfaceFactory;
public class Coordinate {
public static final int WIDTH = 26;
public static final int HEIGHT = 26;
int x;
int y;
Coordinate() {
x = 0;
y = 0;
}
void locateApple() {
Random random = new Random();
x = random.nextInt(WIDTH);
y = random.nextInt(HEIGHT);
}
}
package Snake;
import java.util.Random;
import java.util.Locale;
import java.util.Scanner;
import ui.Event;
import ui.SnakeUserInterface;
import ui.UserInterfaceFactory;
public class Snake {
int lengthOfSnake;
Coordinate headOfSnake = new Coordinate();
Coordinate[] snakePosition = new Coordinate[20];
Snake() {
lengthOfSnake = 2;
}
void startPositionSnake() {
snakePosition[0].x = 1;
snakePosition[0].y = 0;
snakePosition[1].x = 0;
snakePosition[1].y = 0;
}
Object arrays are filled with null values by default. To fill them with the coordinates you have to loop through the array and fill them (see NullPointerException when Creating an Array of objects)
Related
Consider the simplified Kotlin code below wherein a circular reference is resolved during JSONification via #JsonIdentityInfo, when using Jackson. A class Index contains a list indices of other Indexes
import com.fasterxml.jackson.annotation.JsonIdentityInfo
import com.fasterxml.jackson.annotation.ObjectIdGenerators
import com.fasterxml.jackson.databind.ObjectMapper
import java.util.UUID
fun main() {
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator::class, property = "id")
class Index() {
val id = UUID.randomUUID()
val neighbours = mutableListOf<Index>()
}
val n=1000 //does work for n=100
val indices = List(n) {Index()}
indices.forEach { it.neighbours.addAll(indices) }
ObjectMapper().writeValueAsString(indices)
}
The serialization fails for n=1000 but doesn't for n=100 hinting at a scaling issue.
I have gone through several SO answers as well as a very nice Baeldung blog (also found via SO) but those didn't help.
Why is there still a recursion error?
Interestingly the java version of the code works for both ns.
Is this a kotlin specific bug?
the gradle dependency being used
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.13.+"
java version
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class rough {
public static void main(String[] args) throws JsonProcessingException {
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
class Index {
public UUID id = UUID.randomUUID();
List<Index> neighbours = new ArrayList<>();
}
var n = 1000;
List<Index> indices = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
indices.add(new Index());
}
indices.forEach(index -> index.neighbours.addAll(indices));
new ObjectMapper().writeValueAsString(indices);
}
}
I want to define my variables in my game document class, then use some of those variables in my Movement class. However, when I use these variables in my movement class I get tons of Compiling Errors saying that they're all undefined.
Thus my question is, why are my public variables not passed over to my other class? I have imported the class by doing import game; so this leaves me confussed. I'm probably just doing it wrong, but help is much appreciated.
Timeline
addChild((new Movement));
Game Document Class
package
{
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class game extends MovieClip
{
public var area1:Boolean = true;
public var area2:Boolean = false;
public var area3:Boolean = false;
public var player1:Boolean = true;
public var playerPosKeeper_mc:MovieClip = new mc_PlayerPosKeeper();
public var up_dpad:MovieClip = new dpad_Up();
public var down_dpad:MovieClip = new dpad_Down();
public var left_dpad:MovieClip = new dpad_Left();
public var right_dpad:MovieClip = new dpad_Right();
public var menu_dpad:MovieClip = new dpad_Menu();
public var run_dpad:MovieClip = new dpad_Menu();
public var barrierRoof1_game:MovieClip = new game_BarrierRoof();
public var barrierRoof2_game:MovieClip = new game_BarrierRoof();
public var barrierSide1_game:MovieClip = new game_BarrierSide();
public var barrierSide2_game:MovieClip = new game_BarrierSide();
public function game()
{
trace("SUCCESS | Constructed Game Class");
}
}
}
Movement Class
package
{
import game;
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TouchEvent;
import flash.net.dns.AAAARecord;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
public class Movement extends MovieClip
{
var inMotion:Boolean = false;
public function Movement()
{
trace("SUCCESS | Constructed Movement Class");
addChild(playerPosKeeper_mc);
playerPosKeeper_mc.x = 384;
playerPosKeeper_mc.y = 46;
addChild(up_dpad);
up_dpad.x = 55;
up_dpad.y = 336;
addChild(down_dpad);
down_dpad.x = 57;
down_dpad.y = 432;
addChild(left_dpad);
left_dpad.x = 19;
left_dpad.y = 372;
addChild(right_dpad);
right_dpad.x = 118;
right_dpad.y = 372;
addChild(menu_dpad);
menu_dpad.x = 61;
menu_dpad.y = 377;
addChild(run_dpad);
run_dpad.x = 684;
run_dpad.y = 369;
addChild(barrierRoof1_game);
barrierRoof1_game.x = 0;
barrierRoof1_game.y = 0;
addChild(barrierRoof2_game);
barrierRoof2_game.x = 0;
barrierRoof2_game.y = 470;
addChild(barrierSide1_game);
barrierSide1_game.x = 0;
barrierSide1_game.y = 0;
addChild(barrierSide2_game);
barrierSide2_game.x = 790;
barrierSide2_game.y = 0;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
up_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, moveUpTouchBEGIN);
up_dpad.addEventListener(TouchEvent.TOUCH_END, moveUpTouchEND);
}
public function moveUpTouchBEGIN(e:TouchEvent):void
{
trace("Touch Began")
}
public function moveUpTouchEND(e:TouchEvent):void
{
trace("Touch Ended")
}
}
}
You are confused because "public" does not mean "global". Declaring variable as public means you want to grant an access to it to any entity, given the entity knows where that variable is.
Lets see what you have there.
Top display object: stage.
Main timeline: game is a child of stage.
MovieClips up_dpad, down_dpad and so on, all are fields of the game instance.
Movement: instance is a child of game.
In the Movement you are trying to access up_dpad and others, but they are kept as fields of game instance and have nothing to do with the Movement instance. That's why they are outside of Movement's addressing context.
So, if you want to have these variables declared as game fields, you need to address them from the Movement in a correct way.
Forget the timeline. In the Game (for the sake's sake never call classes in lowercase unless at the gunpoint) which is, I believe, a root document class:
public function Game()
{
trace("SUCCESS | Constructed Game Class");
// Pass reference to this instance to the constructor.
var aMove:Movement = new Movement(this);
// Add it as a child.
addChild(aMove);
}
In Movement:
public function Movement(main:Game)
{
trace("SUCCESS | Constructed Movement Class");
// Access variables inside Game instance via given reference.
addChild(main.playerPosKeeper_mc);
main.playerPosKeeper_mc.x = 384;
main.playerPosKeeper_mc.y = 46;
// ...and so on
}
These are basics of Object Oriented Programming. If you want to access anything inside an object, you need to access the object first.
I've got a slight problem, I'm writing a gps tracking app to track several objects at once. The data comes in over a serial interface, this is coming in fine from what I can tell. The issue is that I need to continually update the JPanel where the map is created and displayed.
public JPanel mapDisplay(){
JPanel mapPanel = new JPanel();
mapPanel.setSize(560, 540);
Coordinate start = new Coordinate (-34.9286, 138.6);
trackMap.addMapMarker(new MapMarkerDot(1Lat, 1Lon));
trackMap.setDisplayPosition(start,8);
System.out.println(1Lat);
mapPanel.add(trackMap);
mapPanel.setVisible(true);
return mapPanel;
}
This is what I have and it's happy to display the point once but won't update. If I print out the 1Lat variable in the serial method it continually prints, however it only does it once here.
A lot of the answers I've found refer to setting markers by arrays, however that won't work in this case as the objects I'm tracking could be anywhere.
Any help would be greatly appreciated :)
Is it possible to use a worker thread and not use an ArrayList? I would run the risk of missing data if I do.
Not necessarily. In a SwingWorker, your implementation of the doInBackground() method can publish() results as they become available. Note in particular that "Results from multiple invocations of publish() are often accumulated for a single invocation of process()." In your process(), simply loop through the List<Coordinate>, update the route and repaint() the map.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.gui.jmapviewer.JMapViewer;
import org.openstreetmap.gui.jmapviewer.MapPolygonImpl;
/**
* #see http://stackoverflow.com/a/37193636/230513
*/
public class MapWorkerTest {
private final List<Coordinate> route = new ArrayList<>();
private void display() {
JFrame f = new JFrame("MapWorker");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMapViewer map = new JMapViewer() {
#Override
public Dimension getPreferredSize() {
return new Dimension(640, 480);
}
#Override
public String getToolTipText(MouseEvent e) {
Coordinate c = (Coordinate) getPosition(e.getX(), e.getY());
return c.getLat() + " " + c.getLon();
}
};
map.setToolTipText("");
Coordinate start = new Coordinate(-34.9286, 138.6);
route.add(start);
MapPolygonImpl poly = new MapPolygonImpl(route);
poly.setColor(Color.blue);
map.addMapPolygon(poly);
map.setDisplayPosition(start, 10);
f.add(map);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
new MapWorker(map, start).execute();
}
private class MapWorker extends SwingWorker<Void, Coordinate> {
private final JMapViewer map;
private Coordinate last;
public MapWorker(JMapViewer map, Coordinate start) {
this.map = map;
this.last = start;
}
#Override
protected Void doInBackground() throws Exception {
while (!isCancelled()) {
last = new Coordinate(last.getLat() + 0.0025, last.getLon() + 0.01);
publish(last);
Thread.sleep(1000);
}
return null;
}
#Override
protected void process(List<Coordinate> chunks) {
for (Coordinate c : chunks) {
route.add(c);
}
map.repaint();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new MapWorkerTest()::display);
}
}
Multiple route management left as a exercise.
I have three classes
BaseShape
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.system.System;
public class BaseShape extends MovieClip
{
var isActive:Boolean;
public function BaseShape(iX:int, iY:int)
{
x = iX;
y = iY;
isActive=true;
}
//Other function here
}
}
Pentangular
package {
import flash.display.MovieClip;
public class Pentangular extends BaseShape {
public function Pentangular(iX:int, iY:int) {
super(iX, iY);
}
}
}
PentangularClk
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class PentangularClk extends Pentangular {
public function PentangularClk(iX:int, iY:int) {
super(iX, iY);
Cross.visible=false;
addEventListener(MouseEvent.CLICK, setActive);
}
private function setActive(e:MouseEvent):void{
Tick.visible=!Tick.visible;
Cross.visible=!Cross.visible;
isActive=Tick.visible;
}
}
}
When I use in main (stage) class
package
{
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.ui.Keyboard;
public class Main extends MovieClip
{
var myShape:Array=new Array();
var toVertical:int=0;
var toHorizontal:int=0;
var pressedKeys:Object = { };
public function Main()
{
SpeedShape.value=8;
SpeedShape.minimum=0;
SpeedShape.maximum=20;
SpeedShape.stepSize= 1;
RotationShape.value=8;
RotationShape.minimum=1;
RotationShape.maximum=20;
RotationShape.stepSize= 1;
myShape[0] = new Star(mainShape.width / 2,mainShape.height / 4);
//Next line makes this MovieClip
myShape[1] = new PentangularClk(-1 * mainShape.width / 2,-1 * mainShape.height / 4);
mainShape.addChild(myShape[0]);
mainShape.addChild(myShape[1]);
stage.addEventListener(KeyboardEvent.KEY_DOWN,moveShapeByKeyboard);
stage.addEventListener(KeyboardEvent.KEY_DOWN,moveShapeByKeyboard,true);
stage.addEventListener(KeyboardEvent.KEY_UP,stopShapeByKeyboard);
stage.addEventListener(KeyboardEvent.KEY_UP,stopShapeByKeyboard,true);
}
}
}
UPD: Added on 2016-05-13
There are two MovieClips on my library:
Pentangular
PentangularClk
The PentangularClk are based on Pentangular - it has all shapes from Pentangular.
My SWF is launched and works. But I see the next message:
ArgumentError: Error #1063: Argument count mismatch on Pentangular(). Expected 2, got 0.
at flash.display::Sprite/constructChildren()
at flash.display::Sprite()
at flash.display::MovieClip()
at BaseShape()
at Pentangular()
at PentangularClk()
at Main()
I checked what kind parameters are sent to classes. They are Ok. I don't understand the reason of this message.
Thanks all for your suggestions.
The constructor Pentangular are called twice when PentangularClk is added and when its children shape (Pentangular) is added too.
In the second time, the constructor is called without any parameters.
So, the recommendation of #Selirion fits for me.
I just made default values of iX and iY.
Now it looks like
public function Pentangular(iX:int=0, iY:int=0)
Your function PentangularClk(iX:int, iY:int) expects two variables of integer type, so try (untested) :
var int1 : int = (-1 * mainShape.width / 2);
var int2 : int = (-1 * mainShape.height / 4);
myShape[1] = new PentangularClk(int1, int2);
Alternatively you could try like this...
myShape[1] = new PentangularClk( int(-1 * mainShape.width / 2), int(-1 * mainShape.height / 4) );
For starters let me just say that I am very new to action script and also that I'm not using adobe creative suite, I am using notepad with flex as a compiler. I have two classes, a main class and a class called OBJECT_square.
Here is the MAIN class:
package
{
import flash.display.*; import mx.core.*;
import flash.events.*; import mx.collections.*;
import flash.geom.*; import mx.controls.*;
import flash.text.*; import mx.events.*;
import mx.styles.*;
import mx.containers.*;
public class MAIN extends Sprite
{
public var APPLICATION:Application = Application(Application.application);
public var keyDownText:TextField = new TextField();
public function MAIN()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN,KEY_DOWN);
addEventListener(Event.ENTER_FRAME,STEP);
this.addChild(new OBJECT_square().CREATE(10,100,1));
this.addChild(new OBJECT_square().CREATE(10,200,1));
}
public function STEP():void {}
public function DRAW():void {}
public function KEY_DOWN(event:KeyboardEvent):void
{
keyDownText.text = "Key code: " + event.keyCode;
this.addChild(keyDownText);
}
}
}
Here is the OBJECT_square class:
package
{
import flash.display.*;
import flash.events.*;
public class OBJECT_square extends Sprite
{
public var X:int = 0;
public var Y:int = 0;
public var DEPTH:int = 0;
public var SPRITE:Sprite = new Sprite();
public function CREATE(X:int,Y:int,DEPTH:int):Sprite
{
addEventListener(KeyboardEvent.KEY_DOWN,KEY_DOWN);
this.DEPTH = DEPTH;
this.X = X;
this.Y = Y;
DRAW();
return SPRITE;
}
public function KEY_DOWN(event:KeyboardEvent):void
{
if (event.keyCode == 39) {X += 1; DRAW();}
}
public function DRAW():void
{
SPRITE.graphics.beginFill(0xFF0000,1);
SPRITE.graphics.drawRect(X - 10,Y - 10,20,20);
SPRITE.graphics.endFill();
}
}
}
Now my problem is this. Simply put I would like the square that OBJECT_square draws to move right when I press the right arrow key. Right now I can only get it to be drawn once (though I am actually creating two separate squares in two different spots). Now the thing I need to know is if I have used the keyboard event correctly in OBJECT_square. I used keyboard event in the main class as well to display the last key I pressed but I'm not sure how to use it in a class other than the main one. Also I'm not sure how to 'update' the square so that it is redrawn when it moves, that is remove its old self from the display list and reinsert its new self. The whole kinda point to the code is that the square be 'self-sufficient', ie contains all the code needed to draw it and move it rather than relying on any other class. I basically want it so that once another class has made a square the square is capable of doing everything else on its own.
You don't need to keep manually redrawing the square. Sprites have x and y properties that you can change and will automatically be moved. There is also no reason to be creating a sprite inside a class that is already extending sprite. There are a couple of other weird things you are doing so a fixed up version of your class would look something like:
package
{
import flash.display.*;
import flash.events.*;
public class ObjectSquare extends Sprite
{
public function ObjectSquare (x:int,y:int):void
{
graphics.beginFill(0xFF0000,1);
graphics.drawRect(x,y,30,30);
graphics.endFill();
addEventListener(KeyboardEvent.KEY_DOWN,KEY_DOWN);
}
public function KEY_DOWN(event:KeyboardEvent):void
{
if (event.keyCode == 39)
{
x += 1;
}
}
}
}
package
{
import flash.display.*; import mx.core.*;
import flash.events.*; import mx.collections.*;
import flash.geom.*; import mx.controls.*;
import flash.text.*; import mx.events.*;
import mx.styles.*;
import mx.containers.*;
//rename your class to Main. Should not be all caps
public class Main extends Sprite
{
public var APPLICATION:Application = Application(Application.application);
public var keyDownText:TextField = new TextField();
public function Main()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyPress);
addChild(new ObjectSquare(10,100));
addChild(new ObjectSquare(10,200));
}
public function onKeyPress(event:KeyboardEvent):void
{
keyDownText.text = "Key code: " + event.keyCode;
this.addChild(keyDownText);
}
}
}
You would probably be better off creating a class to handle all your keyboard inputs and then change the relevant objects.