Beispiel #1
0
func New(filename string, sprite sprite.Sprite, a ...interface{}) *ParticleSystem {
	ps := new(ParticleSystem)
	if len(a) == 1 {
		if fps, ok := a[0].(float64); ok {
			if fps != 0.0 {
				ps.updateSpeed = 1.0 / fps
			}
		}
	}

	ps.h = hge.New()
	ps.rand = rand.New(int(timer.Time()))
	ps.rand.Seed()

	ptr := resource.LoadBytes(filename)

	if ptr == nil {
		ps.h.Log("Particle file (%s) seems to be empty.", filename)
		return nil
	}

	// skip the first four bytes
	i := uintptr(4)

	// Ok, First we reflect the ParticleSystemInfo struct
	s := reflect.ValueOf(&ps.Info).Elem()

	// Then we loop through each element, skipping sprite for obvious reasons
	for j := 1; j < s.NumField(); j++ {
		// Then we get the field of the struct
		f := s.Field(j)

		// Here we examine the type
		switch f.Type().String() {
		case "float64":
			// Then we set the structure's field to the value at the current
			// byte(s)
			// We cast the value pointed to by the ptr[i] with unsafe.Pointer
			f.SetFloat(float64(*(*float32)(cast(&ptr[i]))))
			// Next we skip ahead based on the size of the data read
			i += unsafe.Sizeof(float32(0.0))

		case "int":
			f.SetInt(int64(*(*int32)(cast(&ptr[i]))))
			i += unsafe.Sizeof(int32(0))

		case "bool":
			f.SetBool(*(*bool)(cast(&ptr[i])))
			i += unsafe.Sizeof(bool(false))
			i += 3 // padding

		case "color.ColorRGB":
			for k := 0; k < 4; k++ {
				f.Field(k).SetFloat(float64(*(*float32)(cast(&ptr[i]))))
				i += unsafe.Sizeof(float32(0.0))
			}
		}
	}

	ps.Info.Sprite = sprite
	ps.age = -2.0

	ps.particles = make([]particle, hgeMAX_PARTICLES+1)

	return ps
}
Beispiel #2
0
func (h *HGE) Timer_GetTime() float64 {
	return timer.Time()
}