I'm trying to set up Collision detection on the cactus-property items on all cactuses in the TMXmap example from andengine Gles2. I have tried various methods - can anyone give me one that works?
Original Code
Tmxmaps andengine
One suggested solution:
collision detection
Another suggested solution:
from andengine.org
I've tried:
if(pTMXTileProperties.containsTMXProperty("cactus", "true")) {
final Rectangle rect = new Rectangle(pTMXTile.getTileX()+10, pTMXTile.getTileY(),14, 14);
final FixtureDef boxFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 1f);
PhysicsFactory.createBoxBody(mPhysicsWorld, rect, BodyType.StaticBody, boxFixtureDef);
rect.setVisible(false);
mScene.attachChild(rect);
}
This is from AndEngine: Handling collisions with TMX Objects
But I get this error:
Physicsfactory not found
I'm using the TMX example you have there as a basis for my game.
This is the main block of code for collisions:
// Define the block behavior
mPathFinderMap = new IPathFinderMap<TMXLayer>(){
private boolean mCollide;
#Override
public boolean isBlocked(final int pX, final int pY, final TMXLayer pTMXLayer) {
/*
* This is where collisions happen and are detected
*/
mCollide = false;
//Null check. Used since not all tiles have properties
if(pTMXLayer.getTMXTile(pX, pY).getTMXTileProperties(mTiledMap) != null){
//Get tiles with collision property
if(pTMXLayer.getTMXTile(pX, pY).getTMXTileProperties(mTiledMap).containsTMXProperty("COLLISION", "true"))
mCollide = true;
}
if(mTMXmapLoader.getCollideTiles().contains(pTMXLayer.getTMXTile(pX, pY)))
mCollide = true;
return mCollide;
}
};
/*
* This method moves the sprite to the designated location
*/
public void walkTo(TMXTile pFinalPosition) {
if(mHasFinishedPath){
mHasFinishedPath = false;//This prevents overlapping paths when the user double clicks. Used to prevent stutter
//Player coordinates
final float[] lPlayerCordinates = mPlayerSprite.convertLocalToSceneCoordinates(mPlayerSprite.getWidth()/2, mPlayerSprite.getHeight()/2);
// Get the tile the center of the player are currently waking on.
TMXTile lPlayerPosition = SceneManager.mWorldScene.getTouchLayer().getTMXTileAt(lPlayerCordinates[Constants.VERTEX_INDEX_X], lPlayerCordinates[Constants.VERTEX_INDEX_Y]);
mFinalPosition = pFinalPosition;
// Sets the A* path from the player location to the touched location.
if(mPathFinderMap.isBlocked(pFinalPosition.getTileColumn(), pFinalPosition.getTileRow(), SceneManager.mWorldScene.getTouchLayer())){
pFinalPosition = getNextTile(lPlayerPosition, pFinalPosition);
}
// These are the parameters used to determine the
int lFromCol = lPlayerPosition.getTileColumn(); int lFromRow = lPlayerPosition.getTileRow();
int lToCol = pFinalPosition.getTileColumn(); int lToRow = pFinalPosition.getTileRow();
boolean lAllowDiagonal = false;
// Find the path. This needs to be refreshed
AStarPath = mAStarPathFinder.findPath(MAX_SEARCH_DEPTH, mPathFinderMap, 0, 0, mTiledMap.getTileColumns() - 1, mTiledMap.getTileRows() - 1, SceneManager.mWorldScene.getTouchLayer(),
lFromCol, lFromRow, lToCol, lToRow, lAllowDiagonal, mHeuristic, mCostCallback);
//Log.i("AstarPath", "AStarPath " + AStarPath);
//Only loads the path if the AStarPath is not null
Path lPlayerPath = loadPathFound();
//Log.i("AstarPath", "lPlayerPath " + lPlayerPath);
if(lPlayerPath != null)
moveSprite(lPlayerPath);//Moves the sprite along the path
else
mHasFinishedPath = true;//If the path is null the player has not moved. Set the flag to true allows input to effect the sprite
}else{
//Update parameters
mFinalPosition = pFinalPosition;
mWaypointIndex = 0;
}
}
/*
* Updates the path
*/
public void updatePath(TMXTile pFinalPosition) {
//Player coordinates
final float[] lPlayerCordinates = mPlayerSprite.convertLocalToSceneCoordinates(mPlayerSprite.getWidth()/2, mPlayerSprite.getHeight()/2);
// Get the tile the feet of the player are currently waking on.
TMXTile lPlayerPosition = SceneManager.mWorldScene.getTouchLayer().getTMXTileAt(lPlayerCordinates[Constants.VERTEX_INDEX_X], lPlayerCordinates[Constants.VERTEX_INDEX_Y]);
// Sets the A* path from the player location to the touched location.
if(mPathFinderMap.isBlocked(pFinalPosition.getTileColumn(), pFinalPosition.getTileRow(), SceneManager.mWorldScene.getTouchLayer())){
pFinalPosition = getNextTile(lPlayerPosition, pFinalPosition);
}
// Determine the tile locations
int FromCol = lPlayerPosition.getTileColumn();
int FromRow = lPlayerPosition.getTileRow();
int ToCol = pFinalPosition.getTileColumn();
int ToRow = pFinalPosition.getTileRow();
// Find the path. This needs to be refreshed
AStarPath = mAStarPathFinder.findPath(MAX_SEARCH_DEPTH, mPathFinderMap, 0, 0, mTiledMap.getTileColumns()-1, mTiledMap.getTileRows()-1, SceneManager.mWorldScene.getTouchLayer(),
FromCol, FromRow, ToCol, ToRow, false, mHeuristic, mCostCallback);
//Loads the path with the astar specifications
Path lPlayerPath = loadPathFound();
//Moves the sprite along the path
if(lPlayerPath != null){
moveSprite(lPlayerPath);
}else{
//If the path is still null after the path manipulation then the path is finished
mHasFinishedPath = true;
mWaypointIndex = 0;
//mPlayerSprite.stopAnimation();
//AStarPath = null;
}
}
The TMXmapLoader does the rest:
//Get the collision, ext, and changing tiles from the object sets on the map
mCollideTiles = this.getObjectGroupPropertyTiles("COLLIDE", TMXGroupObjects);
mExitTiles = this.getObjectPropertyTiles("EXIT", mTMXObjects);
mChangingTiles = this.getObjectGroupPropertyTiles("CHANGE", TMXGroupObjects);
...
public ArrayList<TMXTile> getCollideTiles(){
return mCollideTiles;
}
...
public ArrayList<TMXTile> getObjectGroupPropertyTiles(String pName, final int pLayer, ArrayList<TMXObjectGroup> pTMXObjectGroups){
ArrayList<TMXTile> ObjectTile = new ArrayList<TMXTile>();
for (final TMXObjectGroup pObjectGroups : pTMXObjectGroups) {
// Iterates through the properties and assigns them to the new variable
for (final TMXObjectGroupProperty pGroupProperties : pObjectGroups.getTMXObjectGroupProperties()) {
//Sees if any of the elements have this condition
if (pGroupProperties.getName().contains(pName)) {
for (final TMXObject pObjectTiles : pObjectGroups.getTMXObjects()) {
int ObjectX = pObjectTiles.getX();
int ObjectY = pObjectTiles.getY();
// Gets the number of rows and columns in the object
int ObjectRows = pObjectTiles.getHeight() / WorldActivity.TILE_HEIGHT;
int ObjectColumns = pObjectTiles.getWidth() / WorldActivity.TILE_WIDTH;
for (int TileRow = 0; TileRow < ObjectRows; TileRow++) {
for (int TileColumn = 0; TileColumn < ObjectColumns; TileColumn++) {
float lObjectTileX = ObjectX + TileColumn * WorldActivity.TILE_WIDTH;
float lObjectTileY = ObjectY + TileRow * WorldActivity.TILE_HEIGHT;
ObjectTile.add(mTMXTiledMap.getTMXLayers().get(pLayer).getTMXTileAt(lObjectTileX, lObjectTileY));
}
}
}
}
}
}
return ObjectTile;
}
I'm not familiar with android development, but the error seems to indicate that PhysicsFactory hasn't been imported. Maybe try adding an import statement like this to the top of your file?
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
Related
EDIT: Sorry, but I am not sure that my questions was closed correcltly. I was suggested this thread but it doesn't answer on my question. I am able to simulate mouse click but it doesn't work correctly as I described in my question.
I am still learning JNA and using it in my Java application (JNA 5.6.0 and jna-platform 5.6.0) but I hope people who familiar with C languages can understand me too because JNA is using WinAPI functions. My OS is Windows 10.
What I have:
Swing application that launches the Warcraft III game, runs the exe file of the game.
Low level keyboard hook that intercepts keystrokes LowLevelKeyboardProc() and calls click() method, which is described below.
Logic that should simulate mouse clicks on the coordinates of the game window (where the Inventory, Skills and Control are located), after pressing certain keys (as shown in the picture below).
The problem is that I cannot achieve the correct execution of a mouse click on the coordinates of the game window.
I want to say in advance that I do not violate the rules of the game's license agreement and I want to use it only for personal purposes for the old version of the game, 1.26. Also, I've seen a similar implementation in other programming languages, but I want to implement it in Java.
Below I am attaching the 3 options that I tried, with a description of the problem:
1. Using User32.INSTANCE.SendMessage()
public void click(KeyBindComponent keyBindComponent) {
final int WM_LBUTTONDOWN = 513;
final int WM_LBUTTONUP = 514;
final int MK_LBUTTON = 0x0001;
Map<String, Integer> cords = getCords(keyBindComponent);
if (!cords.isEmpty()) {
int xCord = cords.get("width");
int yCord = cords.get("height");
LPARAM lParam = makeLParam(xCord, yCord);
user32Library.SendMessage(warcraft3hWnd, WM_LBUTTONDOWN, new WPARAM(MK_LBUTTON), lParam);
user32Library.SendMessage(warcraft3hWnd, WM_LBUTTONUP, new WPARAM(MK_LBUTTON), lParam);
System.out.println("x = " + xCord + " y = " + yCord);
}
}
public static LPARAM makeLParam(int l, int h) {
// note the high word bitmask must include L
return new LPARAM((l & 0xffff) | (h & 0xffffL) << 16);
}
It was expected that an invisible click would be made on the test coordinate point (on the building). But the problem is that the area was allocated instead. I assume that the following sequence was performed: clicking the mouse down in the Сurrent mouse position and moving the cursor to the Сoordinate point for click. But I have no idea why this happened.
2. Using User32.INSTANCE.PostMessage()
public void click(KeyBindComponent keyBindComponent) {
final int WM_LBUTTONDOWN = 513;
final int WM_LBUTTONUP = 514;
Map<String, Integer> cords = getCords(keyBindComponent);
if (!cords.isEmpty()) {
int xCord = cords.get("width");
int yCord = cords.get("height");
LPARAM lParam = makeLParam(xCord, yCord);
user32Library.PostMessage(warcraft3hWnd, WM_LBUTTONDOWN, new WPARAM(0), lParam);
user32Library.PostMessage(warcraft3hWnd, WM_LBUTTONUP, new WPARAM(0), lParam);
System.out.println("x = " + xCord + " y = " + yCord);
}
}
public static LPARAM makeLParam(int l, int h) {
// note the high word bitmask must include L
return new LPARAM((l & 0xffff) | (h & 0xffffL) << 16);
}
The same situation happened,instead of clicking on the coordinates, the area was selected, as well as in the case of SendMessage(), probably I will not re-attach the picture twice.
3. Using User32.INSTANCE.SendInput()
public void click(KeyBindComponent keyBindComponent) {
Map<String, Integer> cords = getCords(keyBindComponent);
if (!cords.isEmpty()) {
int xCord = cords.get("width");
int yCord = cords.get("height");
mouseMove(xCord, yCord);
mouseClick();
System.out.println("x = " + xCord + " y = " + yCord);
}
}
void mouseMove(int x, int y) {
final int MOUSEEVENTF_LEFTUP = 0x0004;
final int MOUSEEVENTF_ABSOLUTE = 0x8000;
INPUT input = new INPUT();
INPUT[] move = (INPUT[]) input.toArray(2);
// Release the mouse before moving it
move[0].type = new DWORD(INPUT.INPUT_MOUSE);
move[0].input.setType("mi");
move[0].input.mi.dwFlags = new DWORD(MOUSEEVENTF_LEFTUP);
move[0].input.mi.dwExtraInfo = new BaseTSD.ULONG_PTR(0);
move[0].input.mi.time = new DWORD(0);
move[0].input.mi.mouseData = new DWORD(0);
move[1].type = new DWORD(INPUT.INPUT_MOUSE);
move[1].input.mi.dx = new LONG(x);
move[1].input.mi.dy = new LONG(y);
move[1].input.mi.mouseData = new DWORD(0);
move[1].input.mi.dwFlags = new DWORD(MOUSEEVENTF_LEFTUP + MOUSEEVENTF_ABSOLUTE);
user32Library.SendInput(new DWORD(2), move, move[0].size());
}
void mouseClick() {
final int MOUSEEVENTF_LEFTUP = 0x0004;
final int MOUSEEVENTF_LEFTDOWN = 0x0002;
INPUT input = new INPUT();
INPUT[] click = (INPUT[]) input.toArray(2);
click[0].type = new DWORD(INPUT.INPUT_MOUSE);
click[0].input.setType("mi");
click[0].input.mi.dwFlags = new DWORD(MOUSEEVENTF_LEFTDOWN);
click[0].input.mi.dwExtraInfo = new BaseTSD.ULONG_PTR(0);
click[0].input.mi.time = new DWORD(0);
click[0].input.mi.mouseData = new DWORD(0);
click[1].type = new DWORD(INPUT.INPUT_MOUSE);
click[1].input.setType("mi");
click[1].input.mi.dwFlags = new DWORD(MOUSEEVENTF_LEFTUP);
click[1].input.mi.dwExtraInfo = new BaseTSD.ULONG_PTR(0);
click[1].input.mi.time = new DWORD(0);
click[1].input.mi.mouseData = new DWORD(0);
user32Library.SendInput(new DWORD(2), click, click[0].size());
}
In this case, there is no click at all on the coordinate point. Instead, when certain keys are pressed, the mouse is clicked in Current mouse position.
By the way, I also tried using Java Robot, but it didn't work for me. Unfortunately the mouse cursor moved (disappeared) by about a milliseconds from the starting position to the point where you need to click and back to the starting position.
Thank you for reading this to the end, I apologize for such a cumbersome explanation.
Can anyone tell me what and where I made a mistake in the code? Since in all 3 options, I did not achieve the expected behavior.
For the 3rd case, you did not use the MOUSEEVENTF_MOVE flag to move the mouse, so the mouse did not actually move. And also according to the document:
If MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain
normalized absolute coordinates between 0 and 65,535
void mouseMove(int x, int y) {
INPUT move[2] = {};
DWORD fScreenWidth = ::GetSystemMetrics(SM_CXSCREEN);
DWORD fScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);
move[0].type = move[1].type = INPUT_MOUSE;
move[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;// Release the mouse before moving it
move[1].mi.dx = MulDiv(x, 65535, fScreenWidth);
move[1].mi.dy = MulDiv(y, 65535, fScreenHeight);
move[1].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
SendInput(2, move, sizeof(INPUT));
}
Then use the MOUSEEVENTF_LEFTDOWN and MOUSEEVENTF_LEFTUP to click the current postion.
Or you can directly merge the mouse move into the click event:
void mouseMoveClick(int x, int y) {
INPUT click[3] = {};
click[0].type = INPUT_MOUSE;
click[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;// Release the mouse before moving it
DWORD fScreenWidth = ::GetSystemMetrics(SM_CXSCREEN);
DWORD fScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);
click[1].type = INPUT_MOUSE;
click[1].mi.dx = click[2].mi.dx= MulDiv(x, 65535, fScreenWidth);
click[1].mi.dy = click[2].mi.dy= MulDiv(y, 65535, fScreenHeight);
click[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
click[2].type = INPUT_MOUSE;
click[2].mi.dwFlags = MOUSEEVENTF_LEFTUP | MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
SendInput(3, click, sizeof(INPUT));
}
If you want to move back to the original position after the mouse click, you can use GetCursorPos to record the current position before moving. Then use mouseMove event or simpler SetCursorPos to return to the position.
void click(int xCord, int yCord) {
//mouseMove(xCord, yCord);
POINT p = {};
GetCursorPos(&p);
mouseMoveClick(xCord, yCord);
SetCursorPos(p.x, p.y);
}
example
What I've tried.
Please help me.. I really don't know.
I think it's related to canvas class.
CustomLineChartRenderer
It seems to me that color is not filled according to x value, but color is filled at once.
It's hard because I'm not used to canvas. Please help me.
Here are three methods for drawing lines and filling in colors.
#Override
protected void drawLinearFill(Canvas c, ILineDataSet dataSet, Transformer trans, XBounds bounds) {
final Path filled = mGenerateFilledPathBuffer;
final int startingIndex = bounds.min;
final int endingIndex = bounds.range + bounds.min;
final int indexInterval = 128;
int currentStartIndex = 0;
int currentEndIndex = indexInterval;
int iterations = 0;
// Doing this iteratively in order to avoid OutOfMemory errors that can happen on large bounds sets.
do {
currentStartIndex = startingIndex + (iterations * indexInterval);
currentEndIndex = currentStartIndex + indexInterval;
currentEndIndex = currentEndIndex > endingIndex ? endingIndex : currentEndIndex;
if (currentStartIndex <= currentEndIndex) {
generateFilledPath(dataSet, currentStartIndex, currentEndIndex, filled);
trans.pathValueToPixel(filled);
final Drawable drawable = dataSet.getFillDrawable();
if (drawable != null) {
drawFilledPath(c, filled, drawable);
} else {
//////Here part of applying color
drawFilledPath(c, filled, dataSet.getFillColor(), dataSet.getFillAlpha());
}
}
iterations++;
} while (currentStartIndex <= currentEndIndex);
}
#Override
protected void drawFilledPath(Canvas c, Path filledPath, int fillColor, int fillAlpha) {
int color = (fillAlpha << 24) | (fillColor & 0xffffff);
if (clipPathSupported()) {
Log.e("clipPathSupported","1");
int save = c.save();
c.clipPath(filledPath);
c.drawColor(color);
c.restoreToCount(save);
} else {
Log.e("clipPathSupported","2");
// save
Paint.Style previous = mRenderPaint.getStyle();
int previousColor = mRenderPaint.getColor();
// set
mRenderPaint.setStyle(Paint.Style.FILL);
mRenderPaint.setColor(color);
c.drawPath(filledPath, mRenderPaint);
// restore
mRenderPaint.setColor(previousColor);
mRenderPaint.setStyle(previous);
}
}
private void generateFilledPath(final ILineDataSet dataSet, final int startIndex, final int endIndex, final Path outputPath) {
final float fillMin = dataSet.getFillFormatter().getFillLinePosition(dataSet, mChart);
final float phaseY = mAnimator.getPhaseY();
final boolean isDrawSteppedEnabled = dataSet.getMode() == LineDataSet.Mode.STEPPED;
final Path filled = outputPath;
filled.reset();
final Entry entry = dataSet.getEntryForIndex(startIndex);
filled.moveTo(entry.getX(), fillMin);
filled.lineTo(entry.getX(), entry.getY() * phaseY);
// create a new path
Entry currentEntry = null;
Entry previousEntry = entry;
for (int x = startIndex + 1; x <= endIndex; x++) {
currentEntry = dataSet.getEntryForIndex(x);
if (isDrawSteppedEnabled) {
filled.lineTo(currentEntry.getX(), previousEntry.getY() * phaseY);
}
filled.lineTo(currentEntry.getX(), currentEntry.getY() * phaseY);
previousEntry = currentEntry;
}
// close up
if (currentEntry != null) {
filled.lineTo(currentEntry.getX(), fillMin);
}
filled.close();
}
You can use shader, same :
mRenderPaint.shader = LinearGradient(fromX, fromY, toX, toY, color1,
color2,
Shader.TileMode.CLAMP)
I have a project for school to take my current pacman program and have pacman traverse the 2-d char array to find a pattern to complete the maze.
I am trying to use a stack and add specific index of my maze to the stack so when pacman reaches the index it pops off and he chooses a direction randomly to another index and so forth until all dots are eaten. My issue is taking my 2d array and finding the index values of the intersections and then adding them to a stack.
I am new to java and not really sure how to approach this I posted my maze I have and some code that will use the stack to find the sequence. Thanks in advanced.
private void create() {
String[] tier = new String[tall];
tier[0] = "|======================================|";
tier[1] = "|......................................|";
tier[2] = "|.====.==========================.====.|";
tier[3] = "|.||||............................||||.|";
tier[4] = "|.====.==========================.====.|";
tier[5] = "|......................................|";
tier[6] = "|.====================================.|";
tier[7] = "|......................................|";
tier[8] = "|.====.======.====----====.======.====.|";
tier[9] = "|.||||........|| ||........||||.|";
tier[10] = "|.||||.======.|| ||.======.||||.|";
tier[11] = "|.||||........|| ||....... ||||.|";
tier[12] = "|.====.======.============.======.====.|";
tier[13] = "|......................................|";
tier[14] = "|.===========..............===========.|";
tier[15] = "|.............===== =====.............|";
tier[16] = "|.=======.===.||$ $||.===.=======.|";
tier[17] = "|.|||||||.===.===== =====.===.|||||||.|";
tier[18] = "|.|||||||......................|||||||.|";
tier[19] = "|.|||||||.====================.|||||||.|";
tier[20] = "|.=======......................=======.|";
tier[21] = "|.==......====================......==.|";
tier[22] = "|.==.====.======........======.====.==.|";
tier[23] = "|....====........======........====....|";
tier[24] = "|======================================|";
for (int i = 0; i < tall; i++) {
array[i] = tier[i].toCharArray();
}
}
public boolean isPattern(Spot b, Spot e) {
Stack<Spot> ss = new Stack<Spot>();
Spot topPost, nextPost;
allOld();
ss.push(b);
markOld(b);
topPost = ss.peek();
while (!ss.empty() && (topPost.compareTo(e) != 0)) {
nextPost = getNextSpot(topPost);
if (nextPost == null) {
ss.pop();
} else {
ss.push(nextPost);
markOld(nextPost);
}
topPost = ss.peek();
}
if (ss.empty()) {
return false;
} else {
return true;
}
}
public void index(int x, int y, int dx, int dy){
x=array.length;
y=array[x].length;
for( int i=0;i <x;i++){
for(int j =0; j<y;j++){
if(array[i].get(i))//this should determine if its aninersection and then add to the stack
}
}
}
}
the last method is where i am getting stuck. I dont know how to get the specific index values. I guess i can enter them manually but I am sure there is an easier way. Please comment if need more context on the problem and Thanks again.
I'm trying to display 550 data points with periodic peaks (the flat line is 61). The problem is, that androidplot isn't drawing all the points correctly! From my log:
ECG I values 61,61,62,63,62,61,61,61,61,67,71,68,61,53,61,61,61,61,61,61,61,61,62,63,64,64,64,63,62,61,61,61
I've got the rangeboundaries set to plot.setRangeBoundaries(0,100, BoundaryMode.AUTO);, but as you can see, the peaks never drop to the 53 data point. I can see this lower point sometimes, but it gets smoothed out a fraction of a second later (as you can see in the screenshot).
My line and point formatter is:
LineAndPointFormatter lapf = new LineAndPointFormatter(p.color, null, null, null);
lapf.getLinePaint().setStrokeJoin(Paint.Join.MITER);
lapf.getLinePaint().setStrokeWidth(1);
I've tried with the both Paint.Join.ROUND and Paint.Join.BEVEL and got the same effect. I've also used the debugger to check that 53 is being inserted into the series.
EDIT
After some debugging, it looks like my pulse loop thread is wrong:
while (keepRunning) {
for (PulseXYSeries j : series) {
for (int k = 0; k < j.plotStep; k++) {
int at = (j.position + k) % j.getSize();
if (j.pulsing) {
if (j.pulsePosition == j.pulseValues.size() - 1) {
j.pulsing = false;
j.pulsePosition = 0;
} else {
try {
int pulseVal = j.pulseValues.get(j.pulsePosition);
j.setY(pulseVal,at);
j.pulsePosition += 1;
} catch(IndexOutOfBoundsException e) {
j.pulsePosition = 0;
}
}
} else {
j.setY(j.pulseValues.get(0), at);
long currTime = SystemClock.elapsedRealtime();
if (currTime - j.getLastPulse() >= j.getPulseDelay()) {
j.pulsing = true;
j.setLastPulse(currTime);
}
}
j.remove(((at + j.eraserSize) % j.getSize()));
}
j.position = (j.position + 1) % j.getSize(); // fixed it by changing +1 to + j.plotStep
}
Thread.sleep(delay);
}
My custom series looks like:
private class PulseXYSeries implements XYSeries {
private List<Integer> pulseValues = new ArrayList<Integer>();
private int pulsePerMinute;
public int pulsePosition;
public int position;
private ArrayList<Integer> values;
private String title;
private long lastPulse;
public boolean pulsing = false;
public int eraserSize = 20;
public int plotStep = 3;
}
I'm attemping to use this code from http://www.openprocessing.org/sketch/7050 to make countries formed using the letters from the name of whatever the country is. But I want to make it so once the user presses the right arrow key, the process will start over again, but instead, created a new country and use the letters of that country. I'm a little stuck- what I have makes it so when you press the right arrow key, it begins to make the next country from where ever the previous function left off. Is there a way to make it so it just starts over instead?
PFont font;
String fontpath = "ArialMT-200.vlw";
int fontstart = 300;
int fontend = 8;
float fontsize = fontstart;
float fontsizedecrease = 0.97;
PImage bg;
PImage australia;
String country1 = "australia.jpg";
String country2 = "austria.jpg";
String letters = "Australia";
char[] chars = new char[52];
int nchars = 0;
int iterations = 500;
int c = 0;
PGraphics letter,lettersquare,drawing;
void setup(){
//initialize the sketch
size(900,600);
//background(255);
//initialize the font
//font = loadFont(fontpath);
///*
for(int i=0;i<letters.length();i++){
boolean found = false;
char lc = letters.charAt(i);
for(int j=0;j<nchars;j++){
if(chars[j]==lc){
found = true;
break;
}
}
if(!found) chars[nchars++] = lc;
}
chars = (char[]) subset(chars,0,nchars);
font = createFont("Arial",200,true,chars);
//*/
textAlign(CENTER,CENTER);
//load the image that will be filled with letters
australia = loadImage(country1);
austria = loadImage(country2);
//france = loadImage(country3);
//guatemala = loadImage(country4);
// italy = loadImage(country5);
// japan = loadImage(country6);
bg = loadImage("background.jpg");
//posterize the image
australia.filter(THRESHOLD,0.4);
australia.filter(BLUR,3);
australia.filter(THRESHOLD,0.6);
austria.filter(THRESHOLD,0.4);
austria.filter(BLUR,3);
austria.filter(THRESHOLD,0.6);
//initialize the drawing buffers
letter = createGraphics((int)fontsize,(int)fontsize,JAVA2D);
lettersquare = createGraphics((int)fontsize,(int)fontsize,P2D);
drawing = createGraphics(width,height,JAVA2D);
drawing.beginDraw();
drawing.background(255);
// THIS STUPID THING NEEDS TO GO HERE!!!!
drawing.image(bg,0,0);
drawing.endDraw();
}
void draw(){
background(255);
if(floor(fontsize)>fontend&&c<letters.length()-1){
if(!letterfit()){
fontsize *= fontsizedecrease;
}else{
c++;
if(c==11){
fontsize *= 0.75;
}
}
tint(255);
image(drawing,0,0);
if(mousePressed){
tint(255,100);
image(australia,0,0);
}
}else{
tint(255);
image(drawing,0,0);
println(c+" "+letters.length());
/*
save("mlk-"+hour()+""+minute()+""+second()+".tif");
exit();
*/
noLoop();
}
}
boolean letterfit(){
letter.beginDraw();
letter.background(255,0);
letter.fill(0);
letter.textAlign(CENTER,CENTER);
letter.translate(fontsize/2,fontsize/2);
letter.rotate(random(TWO_PI));
letter.scale(fontsize/fontstart);
letter.textFont(font);
letter.smooth();
letter.text(letters.charAt(c),0,0);
letter.endDraw();
lettersquare.beginDraw();
lettersquare.background(255);
lettersquare.image(letter,0,0);
lettersquare.filter(ERODE);
lettersquare.filter(ERODE);
lettersquare.endDraw();
for(int i=0;i<iterations;i++){
int x = floor(random(width-fontsize));
int y = floor(random(height-fontsize));
boolean fits = true;
for(int dx=0;dx<fontsize&&fits;dx++){
for(int dy=0;dy<fontsize&&fits;dy++){
if(brightness(australia.get(x+dx,y+dy))>127){
fits = false;
break;
}
if(brightness(lettersquare.get(dx,dy))<127){
if(brightness(drawing.get(x+dx,y+dy))<127){
fits = false;
}
}
}
}
if (keyCode == RIGHT) {
for(int dx=0;dx<fontsize&&fits;dx++){
for(int dy=0;dy<fontsize&&fits;dy++){
if(brightness(austria.get(x+dx,y+dy))>127){
fits = false;
break;
}
if(brightness(lettersquare.get(dx,dy))<127){
if(brightness(drawing.get(x+dx,y+dy))<127){
fits = false;
}
}
}
}
if(fits){
drawing.beginDraw();
drawing.image(letter,x,y);
drawing.endDraw();
return true;
}
}
if(fits){
drawing.beginDraw();
drawing.image(letter,x,y);
drawing.endDraw();
return true;
}
}
return false;
}