Kareler, üçgenler, vb. genişleyen yıldız:
Kareler, üçgenler, vb. genişleyen yıldız:
Yanıtlar:
Bunu yapmanın en kolay yolu önce şekli tasarlamak sonra parçacıkların hareketini hesaplamak olacaktır. Bu cevapta bir kare inşa edeceğim, ancak bu herhangi bir şekil için geçerlidir.
Şeklinizi bir başlangıç noktası etrafındaki göreli konumlar olarak tasarlayarak başlayın.
Şimdi şeklin nasıl genişleyeceğini hesaplamanız gerekiyor. Bunu yapmak için biz sadece gelen vektör işaret hesaplamak origin
her üzere point
çıkarılarak origin
bizim dan pozisyon point
ardından 'ın pozisyonuna normale vektör. vector = normalize(point.x - origin.x, point.y - origin.y)
.
Artık bu vektörü kullanarak noktaların konumunu herhangi bir zamanda hesaplayabiliriz. Noktaların bir sonraki konumunu yaparak hesaplarsınız point.position += point.vector * point.velocity
. Önceki noktamızı kullanarak sözde kod örneği:
// When you start your program you set these values.
point.position = (-3, 3); // Start position. Can be anything.
point.vector = normalize(-3, 3); // Normalized vector.
point.velocity = 3; // Can be anything.
// You do this calculation every frame.
point.position += point.vector * point.velocity;
// point.vector * point.velocity = (-3, 3)
// point.position is now (-6, 6) since (-3, 3) + (-3, 3) = (-6, 6)
Bunu yaptığınızda tüm noktalar her karede 3 birimde dışa doğru hareket edecektir.
notlar
Yani, orada karmaşık parçacık / mermi kalıpları oluşturmak için bir biçimlendirme dili olan BulletML adlı bir proje var . Kodu kesinlikle kendi dilinize taşımanız gerekecek, ancak gerçekten şaşırtıcı şeyler yapabilir.
Örneğin, bu patron , BulletML for Unity3D'nin (yoğun şekilde değiştirilmiş) bir uzantısında yapıldı (bu kalıbın yazarı bu videoyu yükledi ve Misery çılgınca ve iyi 1 ). Bu düşmanın en zor varyasyonu ve BulletML'nin neyi iyi yapabileceğini gösteriyor (ve Misery'nin diğer patronlarına da bak, Wallmaster gibi ).
Ya da, The Last Federation için bir genişletme üzerinde çalışırken yazdığım bir desen olan, daha az mod dostu olan ve yalnızca tek karakterli AZ değişkenleri kullanan sistemin eski bir revizyonunu kullanarak bu örneği gösterebilirim :
Bu halkaları yapan yeşil mermiler, yüksek hızda dönen bir ana mermiden çıkarılır, ancak kendilerinin hiçbir hareketi yoktur. Oyuncuyu daha uzun bir menzilde tutarak, hasar silahlarını düşürmelerini kısıtlayarak ve mobil savunucuların oyuncuyu taciz etmelerine izin veren büyük hasar verir (oyuncu, ortadaki hareketsiz yapı tahrip edildiğinde kazandı).
XML sözdiziminin bu balonları oluşturan kısmı:
<bullet_pattern name="Barrier">
$WallShotAngle B=.3 A=90
$WallShotAngle B=.3 A=-90
$WallShotAngle B=.3 A=0
$WallShotAngle B=.375 A=180
</bullet_pattern>
<var name="WallShotAngle">
<bullet angle="[A]" speed="4000" interval_mult=".01" dumbfire="1" shot_type="GravityWavePurple">
<wait time="[B]" />
<change angle="0" speed="1000" time=".0001" />
<spawn>
<bullet_pattern>
<bullet angle="[A]" speed="0" shot_type="CurveBarGreen" damage_mult="8">
<wait time="12" />
<die />
</bullet>
</bullet_pattern>
</spawn>
<die />
</bullet>
</var>
Ekran görüntüsünde, kaynaktan (dönen) hemen balonun kenarına doğru giden mor "yerçekimi dalgası" çekimlerinden bazılarını görebilirsiniz. despawning. Çok daha karmaşık oldukları için mavi ve sarı çekimleri atladım.
Genişlemedeki diğer kalıplardan biri ( topçu kabuğu ) aslında Misery tarafından yazılmıştır, ancak bazı değişiklikler yaptım. Başlangıçta, uzun menzilli uçan ve ardından tonlarca hasar veren büyük bir havai fişek gösterisine patlayan düşük hasarlı, delici bir atış. Maksimum menzili, oyuncunun başarabileceğinden çok daha yüksekti, esas olarak oyuncuyu kısa menzilde çalışmaya zorladı, bu da av tüfeği etkisi nedeniyle (küçük bir bölgede kümelenmiş daha fazla mermi) diğer NPC birimleri için avantajlıydı.
BulletML ile çalışmak genellikle kolaydır ve şaşırtıcı şeyler yapabilir. Mermiler yön değiştirebilir, hızı değiştirebilir, diğer modelleri ortaya çıkarabilir, erken ölebilir, bir döngüdeki komut koleksiyonunu tekrarlayabilir, gecikmeleri kullanabilir, mermi hareketli görüntüsünü değiştirebilir, ebeveynlerini takip edebilir (ya da değil) ... Ve destekleyemediği her şey içine yazın.
Ciddi bir ateş em up oyunu yapıyorsanız kesinlikle tavsiye ederim. Charanor cevabında bahsedildiği gibi, istenen şekilleri elde etmek için koordinat matematiğini çalıştırmanız gerekecek, ancak BulletML gibi bir mermi motoru size çok daha fazla esneklik kazandıracak ve yeni desenler tasarlamaktan daha fazla zaman harcayacaksınız. nasıl kodlanır.
Charanor'un işaret ettiği gibi, şeklinizi tanımlamak ve daha sonra zaman içinde konumlarını güncellemek için bir dizi nokta kullanabilirsiniz. Aşağıda, noktaları kullanarak bir yıldız şeklinin veya özel bir şeklin nasıl uygulanacağının çalışan bir örneği verilmiştir:
package com.mygdx.gtest;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
public class Test extends ApplicationAdapter{
public SpriteBatch sb;
private StarShape ss, ssBig;
@Override
public void create() {
sb = new SpriteBatch();
Pixmap pmap = new Pixmap(2, 2,Format.RGBA8888);
pmap.setColor(Color.WHITE);
pmap.fill();
ss = new StarShape(50,50,new Texture(pmap), 10, true);
ssBig = new StarShape(250,250,new Texture(pmap), 50, false);
pmap.dispose();
}
@Override
public void render() {
super.render();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
ss.update(Gdx.graphics.getDeltaTime());
ssBig.update(Gdx.graphics.getDeltaTime());
sb.begin();
ss.draw(sb);
ssBig.draw(sb);
sb.end();
}
@Override
public void dispose() {
super.dispose();
}
private class StarShape{
public float progress = 1f;
public Texture bulletTex;
public Array<Vector2> points = new Array<Vector2>();
public Vector2 center;
public StarShape(float x, float y, Texture tex, float initialSize, boolean mathWay){
center = new Vector2(x,y);
bulletTex = tex;
if(mathWay){
// define star shape with maths
float alpha = (float)(2 * Math.PI) / 10;
float radius = initialSize;
for(int i = 11; i != 0; i--){
float r = radius*(i % 2 + 1)/2;
float omega = alpha * i;
points.add(
new Vector2(
(float)(r * Math.sin(omega)),
(float)(r * Math.cos(omega))
)
);
}
}else{
// or define star shape manually (better for non geometric shapes etc
//define circle
points.add(new Vector2(-3f,0f));
points.add(new Vector2(-2.8f,1f));
points.add(new Vector2(-2.2f,2.2f));
points.add(new Vector2(-1f,2.8f));
points.add(new Vector2(0f,3f));
points.add(new Vector2(1f,2.8f));
points.add(new Vector2(2.2f,2.2f));
points.add(new Vector2(2.8f,1f));
points.add(new Vector2(3f,0f));
points.add(new Vector2(2.8f,-1f));
points.add(new Vector2(2.2f,-2.2f));
points.add(new Vector2(1f,-2.8f));
points.add(new Vector2(0f,-3f));
points.add(new Vector2(-1f,-2.8f));
points.add(new Vector2(-2.2f,-2.2f));
points.add(new Vector2(-2.8f,-1f));
// mouth
points.add(new Vector2(-2,-1));
points.add(new Vector2(-1,-1));
points.add(new Vector2(0,-1));
points.add(new Vector2(1,-1));
points.add(new Vector2(2,-1));
points.add(new Vector2(-1.5f,-1.1f));
points.add(new Vector2(-1,-2));
points.add(new Vector2(0,-2.2f));
points.add(new Vector2(1,-2));
points.add(new Vector2(1.5f,-1.1f));
points.add(new Vector2(-1.5f,1.5f));
points.add(new Vector2(1.5f,1.5f));
}
}
public void update(float deltaTime){
this.progress+= deltaTime;
}
public void draw(SpriteBatch sb){
Vector2 temp = new Vector2(0,0);
for(Vector2 point: points){
temp.x = (point.x);
temp.y = (point.y);
temp.scl(progress);
sb.draw(bulletTex,temp.x + center.x,temp.y +center.y);
}
}
}
}