I am working in some game idea with Android and AndEngine, but I can't find a good tiling approach.
Some part of the game will consist on a rectangular grid. Three "styles" are possible, for each square side of the grid or the inner square. For simplicity we can think about gray, blue and red.
The problem is, when I think about making the sprite sheet, I'm not sure how to do it.
This is a quick (and bad drawing) of my first thoughts, being black the grid and green the cuts. Problem with this one is I would need to have up to 512 versions of the line crossing.
Is there a better approach? Can I do that without sprite sheets, just drawing lines and filling rectangles?
Sorry, I can't follow your thoughts completely. But, I understand you are handling a lot of squares and lines in different styles. And that's where you are right, you don't need any Sprites for that, AndEngine has some classes to draw simple things and it is way faster than Sprites.
basic example that reproduces your graphic with lines
// first the green lines (they are under the black ones)
Line[] greenLines = new Line[8];
// from (x0 ,y0) to (x1,y1) with lineWidth=5px
// the outer square
greenLines[0] = new Line(0, 0, 100, 0, 5, vertexBufferObjectManager); // top line
greenLines[1] = new Line(100, 0, 100, 100, 5, vertexBufferObjectManager); // right line
greenLines[2] = new Line(100, 100, 0, 100, 5, vertexBufferObjectManager); // bottom line
greenLines[3] = new Line(0, 100, 0, 0, 5, vertexBufferObjectManager); // left line
// inner horizontal lines
greenLines[4] = new Line(0, 33, 100, 33, 5, vertexBufferObjectManager);
greenLines[5] = new Line(0, 66, 100, 66, 5, vertexBufferObjectManager);
// inner vertical lines
greenLines[6] = new Line(33, 0, 33, 100, 5, vertexBufferObjectManager);
greenLines[7] = new Line(66, 0, 66, 100, 5, vertexBufferObjectManager);
// now the black lines
Line[] blackLines = new Line[4];
blackLines[0] = new Line(0, 15, 100, 15, 5, vertexBufferObjectManager);
blackLines[1] = new Line(0, 81, 100, 81, 5, vertexBufferObjectManager);
blackLines[2] = new Line(15, 0, 15, 100, 5, vertexBufferObjectManager);
blackLines[3] = new Line(81, 0, 81, 100, 5, vertexBufferObjectManager);
// now set the color and attach the lines to the scene (green)
for(Line line: greenLines){
line.setColor(0f,1f,0f);
myScene.attachChild(line);
}
// now set the color and attach the lines to the scene (black)
for(Line line: blackLines){
line.setColor(0f,0f,0f);
myScene.attachChild(line);
}
this above example should actually work. Now you only have to change it and adjust it to your needs. If you want to change a line you could call myLine.setPosition(fromX, fromY, toX, toY); oh and a rectangle is quite simple as well: Rectangle rectangle = new Rectangle(50,50,100,100, 5, vertexBufferObjectManager); for a rectangle that starts at (50,50) and is 100 pixels wide and 100 pixels high. And has a line width of 5 pixels. You can set the color of the Rectangle as you can for the lines. The only problem is, that the rectangle is always filled. If you want an empty rectangle you have to draw it with lines.
public Line buildGrid(int pWidth, int pHeight, float pRed, float pGreen, float pBlue){
Line grid = new Line(0, 0, 0, pHeight);
grid.setColor(0.5f, 0.5f, 0.5f);
int cont = 0;
while(cont < pWidth){
cont += 10;
grid.attachChild(new Line(cont, 0, cont, pHeight));
grid.getLastChild().setColor(pRed, pGreen, pBlue);
}
cont = 0;
while (cont < pHeight){
cont += 10;
grid.attachChild(new Line(0, cont, pWidth, cont));
grid.getLastChild().setColor(pRed, pGreen, pBlue);
}
return grid;
}
Related
Here is the code I use:
Shader mShader0 = new LinearGradient(10 , 0, 66 ,0,
new int[] { Color.RED, Color.GREEN, Color.BLUE },
null, Shader.TileMode.REPEAT); // CLAMP MIRROR REPEAT
pincel1.setShader(mShader0);
canvasG.drawRect( 0, 0, 30, 200, pincel1);
canvasG.drawRect(1250, 0, 1280, 200, pincel1);
canvasG.drawRect(1000, 0, 1030, 200, pincel1);
canvasG.drawRect( 200, 0, 230, 200, pincel1);
canvasG.drawRect( 250, 0, 280, 200, pincel1);
pincel1.setShader(null);
The result is that all the columns are different.
Why are not all the same? What is wrong?
The reason is because the LinearGradient is defined to start at x=10, end at x=66 and repeat after that. When you assign the gradient to the paint, and draw different rectangles, the co-ordinates of the rectangles are used to determine which "part" of the gradient to draw. For example: a rectangle from x=0 and width=56 will contain your complete gradient. Any rectangle after that will repeat the pattern.
For more understanding, if you draw rectangles at x={a, a+56, a+2*56, a+3*56 ..} and width<56 they will contain the same gradient pattern. I hope this explains why the above observations are correct.
I have this code:
public Scene onLoadScene() {
Random randomGenerator = new Random();
pX = randomGenerator.nextInt(CAMERA_WIDTH);
Sprite snow = new Sprite (pX, 1, 30, 30, mTextureSnowRegion);
scene.getLastChild().attachChild(snow);
return scene;
}
I am trying to make a snowfall. I was trying to use a MoveModifier, but nothing is work.
Please help.
I would suggest using a particle system in AndEngine: http://code.google.com/p/andengineexamples/source/browse/src/org/anddev/andengine/examples/ParticleSystemSimpleExample.java
public Scene onLoadScene() {
Random randomGenerator = new Random();
pX = randomGenerator.nextInt(CAMERA_WIDTH);
Sprite snow = new Sprite (pX, 1, 30, 30, mTextureSnowRegion);
scene.getLastChild().attachChild(snow);
return scene;
This looks good. You just need to add MoveYModifer instead of MoveModifier.
And also you should use an GenericPool in AndEngine, because it uses alot of memory to keep creating new Sprite instances and attaching it. Also dont forget to detach it when the sprite is gone off screen.
Check out this
Using this particle code in my game to create snow. My game uses a 800x480 camera.
final RectangleParticleEmitter particleEmitter = new RectangleParticleEmitter(184.0f,44.0f,340,60);
final ParticleSystem particleSystem = new ParticleSystem(particleEmitter, 100, 200, 360, this.mParticleTextureRegion);
particleSystem.addParticleInitializer(new ColorInitializer(1, 1, 1));
particleSystem.addParticleInitializer(new AlphaInitializer(0));
particleSystem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
particleSystem.addParticleInitializer(new VelocityInitializer(-200, 200, -200, 200));
particleSystem.addParticleInitializer(new RotationInitializer(0.0f, 360.0f));
particleSystem.addParticleModifier(new ScaleModifier(1.0f, 1.2f, 0, 5));
particleSystem.addParticleModifier(new ColorModifier(1, 0.98f, 1, 0.96f, 1, 0.82f, 0, 3));
particleSystem.addParticleModifier(new ColorModifier(1, 1, 0.5f, 1, 0, 1, 4, 6));
particleSystem.addParticleModifier(new org.anddev.andengine.entity.particle.modifier.AlphaModifier(0, 1, 0, 1));
particleSystem.addParticleModifier(new org.anddev.andengine.entity.particle.modifier.AlphaModifier(1, 0, 5, 6));
particleSystem.addParticleModifier(new ExpireModifier(3, 6));
I am using similar particle system settins as #UncleIstvan.
final BatchedPseudoSpriteParticleSystem particleSystem = new BatchedPseudoSpriteParticleSystem(
new RectangleParticleEmitter(CAMERA_WIDTH / 2, CAMERA_HEIGHT, CAMERA_WIDTH, 1),
2, 5, 100, mSnowParticleRegion,
this.getVertexBufferObjectManager()
);
particleSystem.setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE);
particleSystem.addParticleInitializer(new VelocityParticleInitializer<Entity>(-3, 3, -20, -40));
particleSystem.addParticleInitializer(new AccelerationParticleInitializer<Entity>(-3, 3, -3, -5));
particleSystem.addParticleInitializer(new RotationParticleInitializer<Entity>(0.0f, 360.0f));
particleSystem.addParticleInitializer(new ExpireParticleInitializer<Entity>(10f));
particleSystem.addParticleInitializer(new ScaleParticleInitializer<Entity>(0.2f, 0.5f));
particleSystem.addParticleModifier(new AlphaParticleModifier<Entity>(6f, 10f, 1.0f, 0.0f));
scene.attachChild(particleSystem);
But I added an entity modifier to each particle:
particleSystem.addParticleInitializer(new RegisterXSwingEntityModifierInitializer<Entity>(10f, 0f, (float) Math.PI * 8, 3f, 25f, true));
It needs a custom particle initializer. In the initializer I register a new modifier to each particle:
#Override
public void onInitializeParticle(Particle<T> pParticle) {
pParticle.getEntity().registerEntityModifier(
new PositionXSwingModifier(mDuration,
mFromValue, mToValue,
mFromMagnitude, mToMagnitude));
}
And the last part is the modifier that uses growing sine wave to create the swinging motion (some parts ommited):
public class PositionXSwingModifier extends SingleValueSpanEntityModifier {
public PositionXSwingModifier(float pDuration, float pFromValue, float pToValue,
float pFromMagnitude, float pToMagnitude) {
// fromValue is usually 0
// toValue means how many times will the sine wave oscillate
// every 2pi is full sin wave
super(pDuration, pFromValue, pToValue);
mFromMagnitude = pFromMagnitude;
mToMagnitude = pToMagnitude;
}
#Override
protected void onSetValue(IEntity pItem, float pPercentageDone, float pValue) {
// current magnitude based on percentage
float currentMagnitude = mFromMagnitude + (mToMagnitude - mFromMagnitude) * pPercentageDone;
// current sine wave value
float currentSinValue = (float) Math.sin(pValue);
// change the x position of the flake
pItem.setX(mInitialX + currentMagnitude * currentSinValue);
}
}
It's based partly on my question here: https://gamedev.stackexchange.com/questions/56475/how-to-simulate-feather-fall-in-box2d
And you can get the full code and the APK to try it out here.
I wanted to make a rounded shape and apply it as a background on a layout. This i have under control, but i wanted to make the background like a progressbar.
that is i want it to look something like this image:
I want to be able to control where the bg change so i guess it should be done in code.
It must be done in a way so i can place text over it
at the moment i have this code for creating a rounded corner shape:
int w = this.getWidth() - this.getPaddingLeft() - this.getPaddingRight();
int h = this.getHeight() - this.getPaddingTop() - this.getPaddingBottom();
int progressWidth = Math.round((w * percent) / 100);
ShapeDrawable shapeDrawable = new ShapeDrawable();
float[] outerR = new float[]{5, 5, 5, 5, 5, 5, 5, 5};
RectF inset = new RectF(0, 0, 0, 0);
float[] innerR = new float[]{0, 0, 0, 0, 0, 0, 0, 0};
RoundRectShape roundRectShape = new RoundRectShape(outerR, inset, innerR);
shapeDrawable.setShape(roundRectShape);
shapeDrawable.getPaint().setColor(progressColor);
shapeDrawable.setBounds(0,0,w,h);
I want to draw five rectangle bars in Android. I have the regtangles, but now I want them to be a bit spaced apart.
I want them to be aligned at the bottom, and with the same distance between them.
for (int i= 0; i<4; i++) {
int ce = heigth[i];
Paint rectanglePaint = new Paint();
rectanglePaint.setARGB(255, 0, 0, 0);
rectanglePaint.setStrokeWidth(2);
rectanglePaint.setColor(Color.BLUE);
rectanglePaint.setStyle(Style.STROKE);
Rect rectangle = new Rect(35+10*ce, 150, 10, 10*ce); //in pixels
//rectangle.offset(50, 50);
rectangle.offsetTo(55+10*ce, 150);
//canvas.translate(10, 0);
canvas.drawRect(rectangle, rectanglePaint);
I have tried with offset, offsetTo, translate, but can't find the logic in using them. I want them all to start at different spots, like they move 35 dip to the right and are all 30 dip wide. Although I add 35 to the left, they still originate from the same spot.
Perhaps height[i] do not change?
Thisn should create four 10x10 rectangles separated 35 px to the left each other. BTW, you do not need to create four Paint objects. Reuse the same for the four rectangles for improved efficiency.
Paint rectanglePaint = new Paint();
rectanglePaint.setARGB(255, 0, 0, 0);
rectanglePaint.setStrokeWidth(2);
rectanglePaint.setColor(Color.BLUE);
rectanglePaint.setStyle(Style.STROKE);
for (int i= 0; i<4; i++) {
Rect rectangle = new Rect(35*i, 150, 35*i+10, 160);
canvas.drawRect(rectangle, rectanglePaint);
}
I want to draw 10 by 10 grid that defines ground plane such that the center is the origin of the world coordinates.
This is the code that is called for each line defined in the grid.
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVerticesBuffer);
gl.glTranslatef(x, y, z);
gl.glRotatef(rz, 0, 0, 1);
gl.glRotatef(rx, 1, 0, 0);
gl.glRotatef(ry, 0, 1, 0);
gl.glDrawArrays(GL10.GL_LINES, 0, 2);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
The problem is I only see one horizontal line. So I think something is wrong.
This is the code that defines the lines:
Line line;
for (int i = 0; i <= 10; i++) {
// horizontal lines
line = new Line(-50, 0, 0, 50, 0, 0, 0, 0, 1, 1); // blue line
line.z = (i * 100) - 50;
lines.add(line);
// draw perspective lines
line = new Line(-50, 0, 0, 50, 0, 0, 0, 0, 1, 1); // blue line
line.x = (i * 100) - 50;
line.ry = 90;
lines.add(line);
}
For each line in the lines collection I call the drawing code in onDrawFrame.
The reason is because you are only drawing one line. glDrawArrays basically draws opengl primitives from the data given. So the coordinates in your buffer mVerticesBuffer are being drawn once by glDrawArrays.
A simple way to do what you want is to:
Rotate/Translate to starting position
Draw your first line with glDrawArrays();
Use gl.glTranslatef(somenumber, 0, 0);
Draw again with the same call to glDrawArrays();
Use gl.glRotatef(90, 0, 1, 0); to rotate around the y-axis (Or whichever axis you are 0 in)
(Maybe translate back in an axis to get to the same start position)
Do the 2nd, 3rd and 4th bullet point again.
A much tidier and more efficient way of doing this would be with pushing and popping matrices but for simplicity this should work if you're new to opengl.
The solution given to you seems fine and should work to solve your problems.
Probably, the best solution is to generate vertices once and store it in a file, you can read the file once and render the grid in one go, that would be much better in terms of performance and speed.